ダックタイピング
CoddyのPythonジャーニー「Object Oriented Programming」セクションの一部 — レッスン 24/64。
ダックタイピングは、オブジェクトが何であるかではなく、何ができるかに焦点を当てます。オブジェクトが必要なメソッドを持っているなら、そのクラス型に関係なく、それを使用することができます。
同じメソッドを持つ、関連のない2つのクラスを以下に示します。
class Duck:
def swim(self):
return "Duck swimming"
def quack(self):
return "Quack!"
class Person:
def swim(self):
return "Person swimming"
def quack(self):
return "Person imitating a duck: Quack!"DuckとPersonは同じ親クラスを継承していませんが、どちらもswim()メソッドとquack()メソッドを持っていることに注目してください。
任意の「アヒル(duck-like)」のようなオブジェクトで動作する関数を作成します:
def make_it_swim_and_quack(duck_like_object):
print(duck_like_object.swim())
print(duck_like_object.quack())この関数はオブジェクトの型を気にしません。オブジェクトが必要なメソッドを持っていることだけを重視します。
両方のクラスでこの関数を使用します:
make_it_swim_and_quack(Duck())
make_it_swim_and_quack(Person())出力:
Duck swimming
Quack!
Person swimming
Person imitating a duck: Quack!別の「アヒルに似た」クラスを追加します:
class Robot:
def swim(self):
return "Robot swimming with propellers"
def quack(self):
return "Robot sound: BEEP BEEP!"
make_it_swim_and_quack(Robot())出力:
Robot swimming with propellers
Robot sound: BEEP BEEP!重要なポイント:ダックタイピングは継承なしでポリモーフィズムを可能にします。オブジェクトが必要なメソッドを持っているなら、それを使用できます。これによりPythonコードは柔軟になり、「許可を得るよりも許しを請う方が簡単である(it's easier to ask forgiveness than permission)」という原則に従います。
チャレンジ
中級このチャレンジでは、さまざまなファイルのようなオブジェクトを使用してダックタイピングを実証するシステムを実装します。
textfile.py:read()およびwrite(data)メソッドを持つTextFileクラスを実装しますdatabase.py: 一致するメソッドシグネチャを持つDatabaseクラスを実装しますnetworkresource.py: 一致するメソッドシグネチャを持つNetworkResourceクラスを実装しますdriver.py- 実装が正しく動作することを確認するためのテストケースを実装します
各ファイルには、実装をガイドする詳細な TODO コメントが含まれています。
チートシート
ダックタイピングは、オブジェクトが何であるかではなく、そのオブジェクトが何ができるかに焦点を当てます。オブジェクトが必要なメソッドを持っているなら、そのクラスの型に関係なく使用することができます。
同じメソッドを共有する、関連のないクラスを用いたダックタイピングの例:
class Duck:
def swim(self):
return "Duck swimming"
def quack(self):
return "Quack!"
class Person:
def swim(self):
return "Person swimming"
def quack(self):
return "Person imitating a duck: Quack!"任意の「アヒル(duck)のような」オブジェクトで動作する関数を作成します:
def make_it_swim_and_quack(duck_like_object):
print(duck_like_object.swim())
print(duck_like_object.quack())
# swim() と quack() メソッドを持つ任意のオブジェクトで動作します
make_it_swim_and_quack(Duck())
make_it_swim_and_quack(Person())ダックタイピングは継承なしでポリモーフィズムを可能にします。オブジェクトが必要なメソッドを持っているなら、それを使うことができます。これによりPythonコードは柔軟になり、「許可を得るよりも許しを請う方が簡単(it's easier to ask forgiveness than permission)」という原則に従います。
自分で試してみよう
# TODO: textfile.pyからTextFileクラスをインポートしてください
# TODO: database.pyからDatabaseクラスをインポートしてください
# TODO: networkresource.pyからNetworkResource classをインポートしてください
def process_data(data_source, data):
# TODO: data_sourceのread()メソッドを呼び出し、その結果を表示してください
# TODO: data_sourceのwrite(data)メソッドを呼び出し、その結果を表示してください
pass
# 異なるデータソースでのテスト - このテストコードは変更しないでください
text_file = TextFile()
database = Database()
network = NetworkResource()
print("Processing text file:")
process_data(text_file, "Hello, world!")
print("\
Processing database:")
process_data(database, "User record")
print("\
Processing network resource:")
process_data(network, "GET request")このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。