Python 的 typing
模块定义了许多鸭子类型(duck typing),例如 typing.SupportsAbs
来表示任何实现 __abs__
特殊方法的类型。
是否可以以某种方式定义自定义鸭子类型(duck typing),以便我可以将它们用作有效的类型注释?
例如,我希望能够注释一个参数应该是 threading.Lock
的鸭子类型(duck typing)等效项,即任何实现 acquire
的对象> 和 release
方法。理想情况下,我可以将这样的参数注释为 SupportsAcquireAndRequire
或 DuckLock
,而不是 object
。
您可以定义一个 abstract base class (ABC)指定接口(interface):
from abc import ABCMeta, abstractmethod
class SupportsAcquireAndRequire(metaclass=ABCMeta):
@abstractmethod
def acquire(self):
pass
@abstractmethod
def release(self):
pass
@classmethod
def __subclasshook__(cls, C):
for method in ('release', 'acquire'):
for B in C.__mro__:
if method in B.__dict__:
if B.__dict__[method] is None:
return NotImplemented
break
else:
return NotImplemented
return True
这基本上就是协议(protocol)(如 typing.SupportsAbs
)的实现方式,尽管没有直接使用 ABCMeta
。
通过给 ABC 一个 __subclasshook__
method ,您可以在 isinstance()
和 issubclass()
测试中使用它,这对于像 mypy
这样的工具来说已经足够好了。 :
>>> from threading import Lock
>>> isinstance(Lock(), SupportsAcquireAndRequire)
True
我是一名优秀的程序员,十分优秀!