[英]How can you test that a python typing Protocol is a subclass of another Protocol?
The obvious solution to the problem is to use issubclass
, but this raises TypeError
(using Python 3.6.7), eg该问题的明显解决方案是使用
issubclass
,但这会引发TypeError
(使用 Python 3.6.7),例如
>>> from typing_extensions import Protocol
>>> class ProtoSubclass(Protocol):
... pass
...
>>> issubclass(ProtoSubclass, Protocol)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/conda/envs/airflow/lib/python3.6/site-packages/typing_extensions.py", line 1265, in __subclasscheck__
raise TypeError("Instance and class checks can only be used with"
TypeError: Instance and class checks can only be used with @runtime protocols
>>> from typing_extensions import runtime
>>> @runtime
... class ProtoSubclass(Protocol):
... pass
...
>>> issubclass(ProtoSubclass, Protocol)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/conda/envs/airflow/lib/python3.6/site-packages/typing_extensions.py", line 1265, in __subclasscheck__
raise TypeError("Instance and class checks can only be used with"
TypeError: Instance and class checks can only be used with @runtime protocols
For more on the topic of python Protocols
, see有关 python
Protocols
主题的更多信息,请参见
In Python 3.6.7, one way to solve this is to use the @runtime_checkable
decorator:在 Python 3.6.7 中,解决此问题的一种方法是使用
@runtime_checkable
装饰器:
>>> from typing_extensions import Protocol
>>> from typing_extensions import runtime_checkable
>>> @runtime_checkable
... class CustomProtocol(Protocol):
... def custom(self):
... ...
...
>>> @runtime_checkable
... class ExtendedCustomProtocol(CustomProtocol, Protocol):
... def extended(self):
... ...
...
>>> issubclass(ExtendedCustomProtocol, CustomProtocol)
True
The selected answer, although not wrong, doesn't reflect the actual use of Protocol
, which is providing structural subtyping.所选答案虽然没有错,但并未反映
Protocol
的实际使用,它提供了结构子类型。 Nominal subtyping was always available to Python 3.名义子类型始终可用于 Python 3。
from typing import Protocol, runtime_checkable
@runtime_checkable
class Closable(Protocol):
def close(self):
...
class AnyClass:
def close(self):
...
issubclass(AnyClass, Closable)
#> True
Also, runtime_checkable
is only needed in the base class, even if the class being checked is a Protocol
subclass.此外,仅在基类中需要
runtime_checkable
,即使被检查的类是Protocol
子类。
class ExtendedProtocol(Closable, Protocol):
...
class AnotherProtocol(Protocol):
def close(self):
...
class NotAProtocol(Closable):
# just inherits the protocol's default implementation
...
issubclass(ExtendedProtocol, Closable)
#> True
issubclass(AnotherProtocol, Closable)
#> True
issubclass(NotAProtocol, Closable)
#> True
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.