16

typing模块包含几个名称如“SupportsInt”(-Float、-Bytes 等)的对象。模块的文档页面上的名称和描述可能会被解读为建议您可以测试对象是否属于“支持__int__()”类型。但是,如果您尝试使用isinstance(),它会给出一个响应,表明这不是您应该做的事情:

>>> isinstance(5, typing.SupportsInt)
(Traceback omitted)
TypeError: Protocols cannot be used with isinstance().

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

>>> issubclass((5).__class__, typing.SupportsInt)
True
>>> issubclass(type(5), typing.SupportsInt)
True

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

4

2 回答 2

1

PEP 484这是模块的 PEP 中给出的所有推理typing

因为 typing.Callable 作为 collections.abc.Callable 的替代品具有双重职责,所以 isinstance(x, typing.Callable) 是通过推迟到 `isinstance(x, collections.abc.Callable) 来实现的。但是,不支持 isinstance(x, typing.Callable[...])。

协议也称为magic method. 这些是大多数 python 协议(完整列表在这里):

>>> dir(object)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', 
'__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__']

typing我还没有找到不支持的明确原因isinstanceissubclass起作用的原因是isinstance使用了__class_不允许的协议typing,而issubclass使用了__subclasshook__允许的协议。我相信原因是功能已经编码collections.abc.Callable,他们不想在typing模块中重新编码。

于 2016-12-09T02:39:53.277 回答
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

于 2016-12-08T02:31:41.343 回答