我有以下代码。
class CustomMetaClass(type):
def __call__(self, *args, **kwargs):
print("Custom call method is invoked from custom meta class.")
class Sample(metaclass=CustomMetaClass):
def method(self):
print("Printing from a method")
我有一个自定义元类和一个普通类(样本)。 “示例”与我的自定义元类相关联。
由于在 Python 中每件事都是一个对象,每当解释器遇到类定义时,就会为用户定义的类创建一个“类型”的实例。 这是通过调用元类的
__call__()
来完成的。
在上面的例子中,Sample 类与我的自定义元类相关联,因此打印语句应该已经执行;但实际上并没有运行。
但是当我创建 Sample (
Sample()
) 实例时,打印方法被调用。据我所知(来自不同的 stackoverflow 问题),相同的__call__()
元类中的方法用于为用户类(在定义类时)以及用户定义类(即:Sample()
)创建实例
有人可以帮忙我错在哪里吗?
但是当我创建 Sample ( Sample() ) 实例时,打印方法 调用。据我所知(来自不同的 stackoverflow 问题), 元类中相同的 call() 方法用于创建 用户类的实例(在定义类时)以及 用户定义的类(即:Sample())
这是一个复杂的主题,结果证明你做错了。 类元类中的
__call__
是当您创建使用该元类定义的类的ordinary 实例时调用的。 (在这种情况下,当你执行Sample()
).
创建类本身时在元类中执行的内容(
class Sample(...):
语句及其主体),元类中的方法__new__
和__init__
就是所谓的。
感知它完全与普通对象发生的事情相同:当您实例化一个类时,用
Sample()
,“Sample”类(即元类)上的__call__
方法是被调用,它的作用是调用__new__
,然后调用类本身的__init__
方法-(在class Sample(...):
的主体中定义的方法。
所以,发生的是,当执行“类”语句时 - 当它的主体被处理时,调用
metaclass的
__call__
metaclass - 通常这是 type.__call__
可能是最奇怪的部分:type
是它自己的元类。这是硬编码在 cPython 的源代码中。而这个type.__call__
的执行会调用metaclass
initand
new. The
call` on the "first stage" metaclass仅在创建类实例时执行。
In [7]: class Meta1(type):
...: def __call__(mcls, *args): # called when a class is created
...: print("at __call__ of Meta1")
...: return super().__call__(*args)
...:
In [8]: class Meta2(type, metaclass=Meta1):
...: def __new__(mcls, *args):
...: print("at __new__ on Meta2")
...: return super().__new__(mcls, *args)
...: def __call__(cls, *args, **kw): # called when an instance is created
...: print ("at __call__ on Meta2")
...: return super().__call__(*args, **kw)
...:
In [9]: class Sample(metaclass=Meta2):
...: def __init__(self):
...: print("at __init__ on Sample")
...:
at __call__ of Meta1
at __new__ on Meta2
In [10]: s = Sample()
at __call__ on Meta2
at __init__ on Sample