0Pricing
Python Academy · レッスン

ポリモーフィズムとダックタイピング

互換性のあるあらゆるオブジェクトで動作するポリモーフィックなコードを記述します。

「ポリモーフィズムとダックタイピング」はCoddyKit上の無料Python Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPython Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Python Academyコースには全4レッスンが含まれています。

導入

ポリモーフィズムを使うと、異なるオブジェクトに同じインターフェースへ応答させられます。ダックタイピングとは、「アヒルのように振る舞うなら、それはアヒルである」という考え方です。

ポリモーフィズムとは

ポリモーフィズムとは「多くの形」を意味します。同じメソッド名でも、異なるオブジェクト上では異なる動作をします。Pythonでは、この考え方を広く採用しています。
class Cat:
    def speak(self): return 'Meow'
class Dog:
    def speak(self): return 'Woof'
for animal in [Cat(), Dog()]:
    print(animal.speak())

ダックタイピング

Pythonでポリモーフィズムを使うために、クラス階層は必要ありません。オブジェクトが適切なメソッドを持っていれば動作します。インターフェースを用意する必要もありません。
class Duck:
    def quack(self): return 'Quack'
class Person:
    def quack(self): return 'I am quacking like a duck'
def make_it_quack(duck):
    print(duck.quack())
make_it_quack(Duck())
make_it_quack(Person())

ポリモーフィックな関数

len()が文字列、リスト、辞書、タプルで動作するのは、それぞれが__len__を実装しているためです。これが組み込みのポリモーフィズムです。
for obj in ['hello', [1,2,3], {'a':1}]:
    print(type(obj).__name__, len(obj))

演算子のオーバーロード

+が整数、浮動小数点数、文字列、リストで動作するのは、それぞれが__add__を異なる方法で実装しているためです。
print(1 + 2)        # int addition
print('a' + 'b')    # string concat
print([1] + [2])    # list concat

プロトコルベースのダックタイピング

反復プロトコルでは、__iter__と__next__を持つ任意のオブジェクトをforループで使用できます。基底クラスは必要ありません。
class Squares:
    def __init__(self, n): self.n,self.i=n,0
    def __iter__(self): return self
    def __next__(self):
        if self.i>=self.n: raise StopIteration
        x=self.i**2; self.i+=1; return x
print(list(Squares(5)))

EAFPとLBYL

EAFP(Easier to Ask Forgiveness than Permission)はtry/exceptを使います。LBYL(Look Before You Leap)はif/hasattrを使います。PythonではEAFPが好まれます。
# LBYL:
if hasattr(obj, 'quack'):
    obj.quack()
# EAFP (Pythonic):
try:
    'hello'.quack()
except AttributeError:
    print('no quack')

安全なディスパッチに使うisinstance()

型ごとに異なる動作が必要な場合は、AttributeErrorを捕捉するよりもisinstance()を使うほうが明確です。
def process(data):
    if isinstance(data, str):
        return data.upper()
    elif isinstance(data, list):
        return [x*2 for x in data]
print(process('hi'))
print(process([1,2,3]))

プロトコルとしての抽象基底クラス

from abc import ABC, abstractmethodを使うと、形式的なプロトコルを定義できます。サブクラスは抽象メソッドを実装する必要があります。
from abc import ABC, abstractmethod
class Drawable(ABC):
    @abstractmethod
    def draw(self): pass
class Circle(Drawable):
    def draw(self): print('O')
Circle().draw()

typing.Protocol(3.8以降)

class MyProtocol(Protocol):を使うと、ABCを使わずに構造的部分型付けを定義できます。静的チェックではmypyと組み合わせて使用できます。
from typing import Protocol
class Quackable(Protocol):
    def quack(self) -> str: ...
def make_quack(x: Quackable) -> str:
    return x.quack()
print('protocol demo')

実践でのポリモーフィズム

適切なインターフェースを持つ任意のオブジェクトを受け入れられるAPIを設計してください。そうすれば、コードを変更せずに機能を拡張できます。
class JSONSerializer:
    def serialize(self, obj): import json; return json.dumps(obj)
class XMLSerializer:
    def serialize(self, obj): return f'<data>{obj}</data>'
def export(data, serializer):
    return serializer.serialize(data)
print(export({'x': 1}, JSONSerializer()))

クイックチェック

Pythonにおけるダックタイピングとは何ですか?

復習

ポリモーフィズム:同じインターフェースで異なる動作を実現します。ダックタイピング:型ではなく振る舞いが重要です。プロトコルはインターフェースを形式ばらずに定義します。EAFP(try/except)はPythonらしい書き方です。

学習を続ける

素晴らしい進み具合です。次の概念を身につけるために、このまま学習を続けてください。

よくある質問

「ポリモーフィズムとダックタイピング」レッスンは無料ですか?

はい。「ポリモーフィズムとダックタイピング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Python Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Python Academyコースには全4レッスンが含まれています。

「ポリモーフィズムとダックタイピング」で何を学びますか?

互換性のあるあらゆるオブジェクトで動作するポリモーフィックなコードを記述します。 ブラウザで直接実行するハンズオンコードでPython Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Python Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPython Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「ポリモーフィズムとダックタイピング」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPython Academyレッスンでコードを書いて実行できますか?

はい。すべてのPython Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 単一継承
  2. メソッドのオーバーライドと super()
  3. 多重継承と MRO
  4. ポリモーフィズムとダックタイピング
← Python Academyに戻る