typing.List在文档中被定义为class typing.List(list, MutableSequence[T]),这应该意味着它是list的子类,但是issubclass()似乎对此感到困惑:
issubclass(typing.List, typing.List)返回True,确认typing.List是一个类。
但是issubclass(typing.List, list)引发了TypeError: issubclass() arg 1必须是一个类,相反!
为了完成混淆,issubclass(list, typing.List)返回True。
我知道我可能误解了一些东西,而不是核心库函数被破坏了,但是我很想知道为什么!
这是Python3.8.7
发布于 2021-05-16 16:30:42
typing.List被定义为class typing.List(list, MutableSequence[T])
是的,也不是。我认为这应该更好地描述行为,但它不是以这种方式实现的。
看看cpython源代码如何列表定义。这是_GenericAlias的一个实例。
如果您使用type(),您也可以找到这个
>>> type(typing.List)
<class 'typing._GenericAlias'>您可以看到这个类已经实现了__subclasscheck__。为了进一步参考,我从cpython复制/引用了这些行:
def __subclasscheck__(self, cls):
if self._special:
if not isinstance(cls, _GenericAlias):
return issubclass(cls, self.__origin__)
if cls._special:
return issubclass(cls.__origin__, self.__origin__)
raise TypeError("Subscripted generics cannot be used with"
" class and instance checks")现在调用issubclass(typing.List, typing.List)时,python调用这个方法,因为这两个参数都是_GenericAlias和._special = True的实例,所以该方法将进入这个分支:return issubclass(cls.__origin__, self.__origin__)。
self__origin__是内置类型list.因此,调用issubclass(typing.List, typing.List)在最后是调用issubclass(list, list)。这意味着您检查的不是typing.List本身,而是表示内置类型。
当您调用issubclass(typing.List, list)时,将输入分支return issubclass(cls, self.__origin__) (因为参数cls是list,而这不是_GenericAlias的实例)。因此,它与issubclass(list, list)的结果是相同的。
使用issubclass(typing.List, list),您可以调用list的__subclasscheck__方法(调用是list.__subclasscheck__(typing.List)的等价物)。
这现在失败了,因为子类检查需要两个参数,即类,而不是实例。但是typing.List是_GenericAlias的一个实例,而不是一个类。因此,这在TypeError中失败了。
https://stackoverflow.com/questions/67552321
复制相似问题