Python的typing
模块定义了许多duck类型,例如typing.SupportsAbs
来表示实现__abs__
特殊方法的任何类型。
是否可以以某种方式定义自定义鸭类型,以便将其用作有效的类型注释?
例如,我希望能够注释参数应该是threading.Lock
的鸭类型等价物,即实现acquire
和release
方法的任何对象。理想情况下,我可以注释SupportsAcquireAndRequire
或DuckLock
这样的论证,而不是object
。
答案 0 :(得分:6)
您可以定义abstract base class (ABC)来指定界面:
for segment in segments:
#calc_function returns a DataFrame that has the same structure as consolidated_df
consolidated_df.loc[idx[segment, :, :], :] = calc_function(segment)
这基本上是协议(如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
)的实现方式,尽管没有直接使用typing.SupportsAbs
。
通过向ABC提供__subclasshook__
method,您可以在ABCMeta
和isinstance()
测试中使用它,这对于像mypy
这样的工具来说已经足够了:
issubclass()
答案 1 :(得分:1)
typing
已更新为支持这样的用例-您可以为此使用typing.Protocol
。
from typing import Protocol, runtime_checkable
@runtime_checkable
class LockLike(Protocol):
def acquire(self) -> None:
...
def release(self) -> None:
...
如您想使用isinstance
一样,您需要@runtimecheckable
,就像Martijn的回答一样。
>>> from threading import Lock
>>> isinstance(Lock(), RuntimeCheckable)
True