Python 3.10中type类为何未实现__class_getitem__与__getitem__方法?
type泛型别名的特殊实现疑问 问题背景
根据Python官方文档说明:
通常,类只有定义了特殊类方法
__class_getitem__()才能被参数化。
同时,关于typing.Type的文档提到:
自3.9版本起弃用:
builtins.type现在支持[]语法。详见PEP 585和泛型别名类型相关说明。
按照上述文档,Python 3.9及之后版本应该可以用type[类名]替代typing.Type[类名],但在PyCharm中使用type[类名]时,IDE会弹出警告:
类
type未定义__getitem__,因此无法在其实例上使用[]运算符。
我在Python 3.10.5的交互式环境中做了验证,结果如下:
Python 3.10.5 (tags/v3.10.5:f377153, Jun 6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> list[int] list[int] >>> list.__class_getitem__(int) list[int] >>> type[int] type[int] >>> type.__class_getitem__(int) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'type' has no attribute '__class_getitem__' >>> type.__getitem__(int) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'type' has no attribute '__getitem__'. Did you mean: '__setattr__'?
我注意到第一篇文档里的“通常”是斜体标注,说明这个规则并不适用于所有类型,因此文档本身没有错误。但我不理解为什么Python要给type做特殊实现(是否因为它是元类?)。IDE的持续警告让我考虑放弃使用type,转而继续使用typing.Type。
更新:部分原因解析
从官方文档中还能找到type未实现__getitem__的原因:
通常,使用方括号对对象进行订阅会调用该对象类中定义的实例方法
__getitem__()。但如果被订阅的对象本身是类,则可能会调用类方法__class_getitem__()。若定义正确,__class_getitem__()应返回GenericAlias对象。
由此可知,type不实现__getitem__是为了避免出现int[str]这类无意义的类型,但这并不是type不实现__class_getitem__的原因——就算实现了这个方法,按照文档描述也不会影响type的实例。
内容的提问来源于stack exchange,提问作者Mechanic Pig

