我正在阅读Python文档和PEPS,但找不到答案.
Generics in python are implemented by subscripting class objects. list[str]
is a list where all elements are integers.
This behaviour is achieved by implementing a special (dunder) classmethod called __class_getitem__
which as the documentation states should return a GenericAlias.
举个例子:
class MyGeneric:
def __class_getitem__(cls, key):
# implement generics
...
这对我来说似乎很奇怪,因为文档还显示了一些代码,类似于面对下标对象时解释器所做的事情,并显示在对象的元类上定义__getitem__
和在对象本身上定义__class_getitem__
总是 Select 元类‘__getitem__
.这意味着无需在语言中引入新的特殊方法即可实现与上面的功能相同的类.
具有相同行为的类的一个示例:
class GenericMeta(type):
def __getitem__(self, key):
# implement generics
...
class MyGeneric(metaclass=GenericMeta):
...
稍后,文档还显示了一个使用元类的__getitem__
作为未被调用的__class_getitem__
的示例的Enum
.
我的问题是,为什么首先引入__class_getitem__
类方法?
它似乎做了与元类‘__getitem__
完全相同的事情,但增加了复杂性,并且需要在解释器中编写额外的代码来决定调用哪个方法.所有这些都没有额外的好处,因为除非专门调用DUnder方法(一般不应该这样做),否则每次定义两者都只会调用相同的方法.
我知道以这种方式实现泛型是不受欢迎的.通常的做法是将已经定义了__class_getitem__
的类划分为子类,比如typing.Generic
,但我仍然很好奇为什么会这样实现该功能.