Metaclasses and when/how functions are called
我正在尝试学习在Python3中元类是如何工作的。我想知道的是:调用了哪些函数,按什么顺序,以及它们的签名和返回。
例如,我知道当用参数
我觉得我很理解
下面是一些我一直在纠结的代码来回答我的问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #!/usr/bin/env python3 class Logged(type): @classmethod def __prepare__(cls, name, bases): print('In meta __prepare__') return {} def __call__(subclass): print('In meta __call__') print('Creating {}.'.format(subclass)) return subclass.__new__(subclass) def __new__(subclass, name, superclasses, attributes, **keyword_arguments): print('In meta __new__') return type.__new__(subclass, name, superclasses, attributes) def __init__(subclass, name, superclasses, attributes, **keyword_arguments): print('In meta __init__') class Thing(metaclass = Logged): def __new__(this, *arguments, **keyword_arguments): print('In sub __new__') return super(Thing, this).__new__(this) def __init__(self, *arguments, **keyword_arguments): print('In sub __init__') def hello(self): print('hello') def main(): thing = Thing() thing.hello() if __name__ == '__main__': main() |
通过这个和一些谷歌搜索,我知道
这段代码的输出会打印"hello",因此正在创建一个实例,这会进一步混淆init。输出结果如下:
1 2 3 4 5 6 7 | In meta __prepare__ In meta __new__ In meta __init__ In meta __call__ Creating <class '__main__.Thing'> In sub __new__ hello |
任何帮助理解元类的帮助都将不胜感激。我读了很多教程,但我错过了其中的一些细节。
首先:
元类的工作方式与类完全相同,即当您调用它们时,它们会生成一个对象。类和元类都是工厂。区别在于,元类在调用时生成类对象,类在调用时生成实例。
类和元类都定义了默认的
您生成了自己的
您可能会问:但是
在编写元类时,如果希望自定义调用该类时所发生的事情,则只应实现
如果我从您的元类中删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | >>> class Logged(type): ... def __new__(subclass, name, superclasses, attributes, **keyword_arguments): ... print('In meta __new__') ... return type.__new__(subclass, name, superclasses, attributes) ... def __init__(subclass, name, superclasses, attributes, **keyword_arguments): ... print('In meta __init__') ... >>> class Thing(metaclass = Logged): ... def __new__(this, *arguments, **keyword_arguments): ... print('In sub __new__') ... return super(Thing, this).__new__(this) ... def __init__(self, *arguments, **keyword_arguments): ... print('In sub __init__') ... def hello(self): ... print('hello') ... In meta __new__ In meta __init__ >>> thing = Thing() In sub __new__ In sub __init__ |
在元类的
1 2 3 4 | def __call__(subclass): print('In meta __call__') print('Creating {}.'.format(subclass)) return super().__call__(subclass) |
印刷品:
1 2 3 | Creating <class '__main__.Thing'>. In sub __new__ In sub __init__ |