我试图了解Python的类型注释是如何工作的(例如List
和Dict
-不是list
或dict
)。具体来说,我对isinstance(list(), List)
的工作原理感兴趣,以便我可以创建自己的自定义注释。
我看到List
被定义为:
class List(list, MutableSequence[T], extra=list):
. . .
我熟悉metaclass = xxx
但我找不到有关此extra = xxx
的任何文档。这是一个关键字还是只是一个参数,如果是这样,它从何而来,它是否起到了我所追求的作用?它甚至与isinstance
有关吗?
isinstance()
和issubclass()
在object.__instancecheck__()
和object.__subclasscheck__()
中都有钩子,typing
泛型也使用。
如果你想提供你自己的泛型,你真的想研究typing
模块源代码,特别是如何使用GenericMeta
和Generic
来定义其他泛型类型,如List
;大多数这样的检查委托给abc.ABCMeta.__subclasshook__
。你可以用这样的钩子定义你自己的ABC,然后定义一个泛型来子类化它。
这里的GenericMeta
元类也赋予了extra
关键字参数的含义。这样的内部结构仍然很少有文档,因为typing
实现仍在不断变化,模块仍然是临时的。extra
参数存储为__extra__
,并在自定义__subclasshook__
实现中使用;对于extra=list
来说,它只是归结为将isinstance(something, List)
翻译成isinstance(something, list)
。
请注意,对运行时检查的支持是故意限制的;静态类型检查器实际上不会运行这些钩子。有关开发人员如何考虑如何为复杂的自定义类提供更好的支持,请参阅mypy跟踪器中的结构子类型讨论,这些自定义类可能会也可能不会实现足够的方法来被视为映射或序列或类似方法。