base class 列表中的赋值

Assignment inside base class list

在阅读 typing 模块源代码时,我注意到以下内容:

class _SpecialForm(_Final, _Immutable, _root=True):
    ...

此处,基本 class 列表中有一个赋值。

稍后签入:

class _Final:
    def __init_subclass__(self, *args, **kwds):
        if '_root' not in kwds:
            raise TypeError("Cannot subclass special typing classes")

_root 到底去哪儿了?文档将其称为 "class keyword arguments" (https://docs.python.org/3/reference/datamodel.html#object.init_subclass),但我找不到任何关于此的更多信息。

class 关键字参数是在 class 声明中传递的任何关键字参数。只有一个这样的参数有特殊处理 - metaclass= - 这个参数指示将用于提供 metaclass.

的可调用对象

那里的任何其他关键字参数按原样传递给 metaclass __new____init__ 方法,以及任何 superclass __init_subclass__ 方法.这些没有以特殊方式处理,最重要的是,它们不是 "base classes" - 前面提到的方法将像任何 Python 方法一样正常接收这些关键字参数:它们可以在方法签名中声明,或者他们可能会接受 **kwargs 字典(就是这种情况)。

值得一提的是,在 superclasses 中使用适当的 __init_subclass__ 方法传递此类参数将 "swallow" 它,class 声明将失败并显示TypeError 由于无法识别 object__init_subclass__ 的参数。相比之下,__new____init__type class 上的默认 metaclass 实现将简单地忽略传递的任何额外关键字。

因此:

In [1]: class A(test=None): 
   ...:     pass 
   ...:            

失败:

TypeError: __init_subclass__() takes no keyword arguments

同时:

In [2]: class A: 
   ...:     def __init_subclass__(cls, **kwd): 
   ...:         super().__init_subclass__(cls)
   ...:                                                                                 

In [3]: class B(A, test=None): 
   ...:     pass 
   ...:           

工作没有问题。 (A.__init_subclass__ kwd 将被传递 {"test": None})