【问题标题】:How can you test that a python typing Protocol is a subclass of another Protocol?你如何测试一个 python 类型的协议是另一个协议的子类?
【发布时间】:2020-04-15 02:50:22
【问题描述】:

该问题的明显解决方案是使用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

【问题讨论】:

    标签: python inheritance protocols typing


    【解决方案1】:

    选择的答案虽然没有错,但并不能反映Protocol 的实际用途,它提供了结构子类型。 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
    

    此外,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
    

    【讨论】:

      【解决方案2】:

      有关 python Protocols 的更多信息,请参阅

      在 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
      

      【讨论】:

        猜你喜欢
        • 2020-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-27
        • 2018-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多