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}
)
在阅读 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}
)