python class 继承中的关键字参数

Keyword arguments in python class inheritance

您好,我最近在看 Python 中的 metaclass

我了解到我们可以通过这种方式将元class附加到class:

class Metaclass(type):
    ...

class MyClass(metaclass=Metaclass):
    ...

想知道上面例子中关键字参数(metaclass=...)的原理是什么。 doc

中似乎没有相关描述

我知道函数有关键字参数,但我从未见过这种形式出现在 class 继承中。

我们知道我们可以通过这种方式使用type()函数创建一个class

cls = type(class_name, (base_class,), {func_name: func_ref})

考虑到 metaclass=... 形式,在使用 type() 而不是 class 关键字创建 class 时如何传递 metaclass?

感谢 Whosebugers!

Yes I've looked this, but it doesn't provide something about principle of keyword argument in class inheritance, I am still confused

metaclass=... 与继承无关。

Python 中的一切都是对象。因此,当您定义 class MyClass 时,不仅 MyClass() 是一个对象,而且 class MyClass 本身也是一个对象。

MyClass()MyClass的一个实例,很简单。

但是如果MyClass也是一个对象,那么class它是什么的实例呢?

如果您什么都不做,对象 (!)MyClass 是 class type.

的一个实例

如果你做 class MyClass(metaclass=Metaclass) 那么 MyClassMetaclass 的实例。

考虑

class Metaclass(type):
    pass

class MyClass1:
    pass

class MyClass2(metaclass=Metaclass):
    pass

MyClass1MyClass2 都继承自 object 并且只有 object.

>>> MyClass1.__mro__
(<class '__main__.MyClass1'>, <class 'object'>)
>>> MyClass2.__mro__
(<class '__main__.MyClass2'>, <class 'object'>)

但它们的类型不同:

>>> type(MyClass1)
<class 'type'>
>>> type(MyClass2)
<class '__main__.Metaclass'>

你什么时候需要这个?通常,你不会。当你这样做的时候,你就是在做那种你已经知道原因和方法的元编程。

通常,与 class 语句一起使用的关键字参数会传递给 __init_subclass__,以供该函数认为合适的方式使用。然而,metaclass 被代码生成器本身用来确定调用什么来定义 class.

metaclass 不是要传递给 type 调用的参数;它是被称为 而不是 type 的可调用对象。粗略地说,

class MyClass(metaclass=Metaclass):
    ...

变成了

MyClass = Metaclass('MyClass', (), ...)

type 只是默认的 metaclass.

(有关如何执行 class 语句的详细信息可以在语言文档 in Section 3.3.3 中找到。)


请注意,元class 不一定是type 的子class。你可以用 metaclasses 做真正可怕的事情,比如

>>> class A(metaclass=lambda x, y, z: 3): pass
...
>>> type(A)
<class 'int'>
>>> A
3

metaclassreturns是什么并不重要,只要它接受 3 个参数即可。

不过,请不要编写这样的实际代码。 class 语句应该产生至少 类似于 类型的东西。


从某种意义上说,class 语句没有其他语句那么神奇。例如,def 语句无法定制为生成 function 实例以外的东西,并且通过显式调用 types.FunctionType 来创建 function 对象要困难得多。