"协议不能与isinstance()一起使用" - 为什么不呢?

Ham*_*ite 14 python isinstance python-3.x

typing模块包含几个名称为"SupportsInt"(-Float,-Bytes等)的对象.可能会读取该模块的名称和文档页面的说明,以表明您可以测试对象是否属于"支持__int__()" 类型.但是如果你尝试使用isinstance()它,它会给出一个响应,表明这不是你想要做的事情:

>>> isinstance(5, typing.SupportsInt)
(Traceback omitted)
TypeError: Protocols cannot be used with isinstance().
Run Code Online (Sandbox Code Playgroud)

另一方面,您可以使用issubclass():

>>> issubclass((5).__class__, typing.SupportsInt)
True
>>> issubclass(type(5), typing.SupportsInt)
True
Run Code Online (Sandbox Code Playgroud)

在这种情况下,什么是"协议"?为什么不允许isinstance()以这种方式使用?

Ale*_*ers 11

如果您遇到这个问题想要解决该错误(就像我一样),解决方案是用以下内容装饰协议类@runtime_checkable

from typing import Protocol, runtime_checkable

@runtime_checkable
class StorageProtocol(Protocol):
    ...
Run Code Online (Sandbox Code Playgroud)

@typing.runtime_checkable

将协议类标记为运行时协议。

isinstance()这样的协议可以与和 一起使用issubclass()

storage = ...  # get something that must implement StorageProtocol
if not isinstance(storage, StorageProtocol):
    raise RuntimeError(...)
Run Code Online (Sandbox Code Playgroud)


小智 0

正如文档所述At runtime, isinstance(x, T) will raise TypeError. In general, isinstance() and issubclass() should not be used with types.:(https://docs.python.org/3/library/typing.html?highlight=typing#typing.TypeVar

  • 这是对所发生情况的描述。问题是问为什么会出现这种行为。您回答了与所提出的问题不同的问题。 (7认同)