python 类继承中的关键字参数



你好,我最近正在寻找Python中的metaclass

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

class Metaclass(type):
...
class MyClass(metaclass=Metaclass):
...
  • 第一个问题

我想知道上面示例中关键字参数(metaclass=...)的原则是什么。文档中似乎没有对此进行描述

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

  • 第二个问题

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

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

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

谢谢叠花!

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

元类不是传递给type调用的参数;而是被调用的可调用对象而不是type。粗略地说,

class MyClass(metaclass=Metaclass):
...

变成了

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

type只是默认元类。

(有关如何执行class语句的血腥细节可以在语言文档的第 3.3.3 节中找到。


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

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

元类返回什么并不重要,只要它接受 3 个参数即可。

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


从某种意义上说,class语句不如其他语句那么神奇。 例如,def语句不能自定义以生成除function实例以外的其他内容,并且通过显式调用types.FunctionType来创建function对象要困难得多。

是的,我已经看过这个了,但它没有提供关于类继承中关键字参数的原则,我仍然很困惑

metaclass=...与继承无关。

Python 中的所有内容都是一个对象。因此,当你定义类MyClass时,不仅MyClass()是一个对象,而且类MyClass本身也是一个对象。

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

但是,如果MyClass也是一个对象,那么它是哪个类的实例?

如果您什么都不做,则对象 (!MyClass是类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'>

你什么时候需要这个?通常,你不会。当你这样做时,你会做那种元编程,你已经知道为什么和如何。

最新更新