Protocolとダックタイピング
動的型付け言語のいいところはダックタイピングが気軽にできること。
3.7以前
def greet(o):
print(f'Hi {o.name}!')
3.7以前は引数oにnameがあることを保証するにはnameを持つ方Personを定義して、タイプヒント用いてしばる必要があった。
def greet(o: Person):
print(f'Hi {o.name}!')
ただ、この関数を安全に使おうと思うとPersonを継承しなければならず、Dog型のオブジェクトをパラメータとして渡そうと思うとPersonを継承しなければならず、おかしな継承を強いられる。
3.8以降
Python3.8からProtocolが追加された。
PEP544にあるように、ダックタイピングを安全に行うために便利。
from typing import Protocol
class HaveName(Protocol):
@property
def name(self) -> str:
return None
Protocalを継承したこのようなクラスを定義して、nameをプロパティに持つクラスを作ると、継承がいらなくなる。
class Person:
def __init__(self, name):
self._name = name
@property
def name(self) -> str:
return self._name
def greet(o: HaveName):
print(f'Hi! {o.name}')
greet(Person('name'))