自定义鸭子类型的Python类型注释 [英] Python type annotation for custom duck type
问题描述
Python的typing
模块定义了许多鸭子类型,例如typing.SupportsAbs
代表任何实现__abs__
特殊方法的类型.
Python's typing
module defines a number of duck types, e.g., typing.SupportsAbs
to represent any type that implements the __abs__
special method.
是否有可能以一种自定义的鸭子类型定义方式,以便可以将它们用作有效的类型注释?
Is it possible to define custom duck types in a way such that I can use them as valid type annotations?
例如,我希望能够注释一个参数应该是threading.Lock
的鸭子类型等效项,即,任何实现acquire
和release
方法的对象.理想情况下,我可以注释诸如SupportsAcquireAndRequire
或DuckLock
这样的参数,而不是object
.
For example, I would like to be able to annotate that an argument should be a duck-type equivalent of a threading.Lock
, i.e., any object that implements acquire
and release
methods. Ideally, I could annotate such an argument as SupportsAcquireAndRequire
or DuckLock
, rather than object
.
推荐答案
您可以定义抽象基类(ABC)以指定接口:
You can define an abstract base class (ABC) to specify the 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
基本上,这是协议(如typing.SupportsAbs
)的实现方式,尽管不直接使用ABCMeta
.
This is basically how the protocols (like typing.SupportsAbs
) are implemented, albeit without directly using ABCMeta
.
通过为ABC提供 __subclasshook__
方法,您可以在isinstance()
和issubclass()
测试中使用它,对于 mypy
:
By giving the ABC a __subclasshook__
method, you can use it in isinstance()
and issubclass()
tests, which is more than good enough for tools like mypy
:
>>> from threading import Lock
>>> isinstance(Lock(), SupportsAcquireAndRequire)
True
这篇关于自定义鸭子类型的Python类型注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!