我试图理解Python的类型注释是如何工作的(例如List
和Dict
- 不是list
或dict
)。具体来说,我对isinstance(list(), List)
如何工作感兴趣,以便我可以创建自己的自定义注释。
我看到List
定义为:
class List(list, MutableSequence[T], extra=list):
. . .
我熟悉metaclass = xxx
,但我找不到关于此extra = xxx
的任何文档。这是一个关键字还是一个参数,如果是这样的话,它来自哪里,它会做我想要的事情?它甚至与isinstance
相关吗?
答案 0 :(得分:8)
isinstance()
和issubclass()
在object.__instancecheck__()
和object.__subclasscheck__()
中有挂钩 typing
仿制品也会使用。
如果您想提供自己的泛型,那么您真的想要研究typing
module source code,特别是如何使用GenericMeta
和Generic
来定义其他通用类型,例如{{1} };大部分此类检查都委托给abc.ABCMeta.__subclasshook__
。您可以使用这样的钩子定义自己的ABC,然后定义一个子类化它的Generic。
这里的List
元类也提供了GenericMeta
关键字参数含义。由于extra
实现仍在不断变化,因此模块仍然是provisional,因此这些内部结构仍然很少被记录。 typing
参数存储为extra
,用于custom __subclasshook__
implementation;对于__extra__
,它只是将extra=list
翻译为isinstance(something, List)
。
请注意,对运行时检查的支持是故意限制的;静态类型检查器实际上不会运行这些钩子。请参阅mypy跟踪器中的structural subtyping discussion,以进一步讨论开发人员如何考虑如何为复杂的自定义类提供更好的支持,这些自定义类可能会或可能不会实现足够的方法来被视为映射或序列或类似。