我已经制作了一个新的模拟模块来运行测试,这里是它的链接:
#! /usr/bin/env python3
import sys as system
import os as operating_system
from functools import partial
from time import perf_counter as counter
class Meta(type):
@classmethod
def __prepare__(instance, name, supers, *list, **map):
print('{} in meta prepare'.format(name))
return {}
def __new__(instance, name, supers, attributes, *list, **map):
print('{} in meta new'.format(name))
return instance
def __init__(self, name, supers, attributes, *list, **map):
print('{} in meta init'.format(self))
def __call__(self, *list, **map):
print('{} in meta call'.format(self))
return type.__call__(self)
print('after call')
class Super(object):
def __new__(instance, *list, **map):
print('{} in Super new'.format(instance))
return instance
def __init__(self, *list, **map):
print('{} in Super init'.format(self))
def __call__(self, *list, **map):
print('{} in Super call'.format(self))
return object.__call__(self)
class Other(object):
def __new__(instance, *list, **map):
print('{} in Other new'.format(instance))
return instance
def __init__(self, *list, **map):
print('{} in Other init'.format(self))
def __call__(self, *list, **map):
print('{} in Other call'.format(self))
return object.__call__(self)
class MetaSuper(object, metaclass = Meta):
def __new__(instance, *list, **map):
print('{} in MetaSuper new'.format(instance))
return instance
def __init__(self, *list, **map):
print('{} in MetaSuper init'.format(self))
def __call__(self, *list, **map):
print('{} in MetaSuper call'.format(self))
return object.__call__(self)
class DoubleSuper(Super, MetaSuper):
def __new__(instance, *list, **map):
print('{} in DoubleSuper new'.format(instance))
return instance
def __init__(self, *list, **map):
print('{} in DoubleSuper init'.format(self))
Super.__init__(self, *list, **map)
MetaSuper.__init__(self, *list, **map)
def __call__(self, *list, **map):
print('{} in DoubleSuper call'.format(self))
return object.__call__(self)
class SuperThenMeta(Super, metaclass = Meta):
def __new__(instance, *list, **map):
print('{} in SuperThenMeta new'.format(instance))
return instance
def __init__(self, *list, **map):
print('{} in SuperThenMeta init'.format(self))
Super.__init__(self, *list, **map)
def __call__(self, *list, **map):
print('{} in SuperThenMeta call'.format(self))
return object.__call__(self)
class Triple(Super, Other, metaclass = Meta):
def __new__(instance, *list, **map):
print('{} in Triple new'.format(instance))
return instance
def __init__(self, *list, **map):
print('{} in Triple init'.format(self))
Super.__init__(self, *list, **map)
Other.__init__(self, *list, **map)
def __call__(self, *list, **map):
print('{} in Triple call'.format(self))
return object.__call__(self)
class Simple(Super):
def __new__(instance, *list, **map):
print('{} in Simple new'.format(instance))
return instance.__init__(instance, *list, **map)
def __init__(self, *list, **map):
print('{} in Simple init'.format(self))
Super.__init__(self, *list, **map)
Other.__init__(self, *list, **map)
def __call__(self, *list, **map):
print('{} in Simple call'.format(self))
return object.__call__(self)
def main():
#thing = SuperThenMeta()
#other = DoubleSuper()
last = Super()
simp = Simple()
trip = Triple()
if __name__ == '__main__':
main()
简而言之,我在这些工作部件之间尝试了几种不同的设置。
如果我运行这个,这就是输出结果:
MetaSuper in meta prepare
MetaSuper in meta new
SuperThenMeta in meta prepare
SuperThenMeta in meta new
Triple in meta prepare
Triple in meta new
<class '__main__.Super'> in Super new
<class '__main__.Simple'> in Simple new
<class '__main__.Simple'> in Simple init
<class '__main__.Simple'> in Super init
<class '__main__.Simple'> in Other init
Traceback (most recent call last):
File "./metaprogramming.py", line 134, in <module>
main()
File "./metaprogramming.py", line 131, in main
trip = Triple()
TypeError: __new__() missing 3 required positional arguments: 'name', 'supers', and 'attributes'
从这里,我有几个问题:
我是否应该在new函数的结尾处调用instance.init(instance, *list, **map)?我认为不需要,但是将其添加到“Simple”示例中似乎起作用了,而“Super”从未达到其init。我认为通过在自己的调用方法中调用object.call,这将由其默认实现处理,但整个程序中没有进行__call__。
为什么调用Triple()会首先调用元类的new?如果这是正常的,那么这是否是具有元类的任何类的典型特征?这与超类的类似行为吗?
我希望在这个列表中找到call。它在对象的创建过程中(例如[prepare]、new、init)不会被调用吗?
__new__
方法的第一个参数是新实例。实际上,它的第一个参数是类本身。__new__
方法的作用是创建新实例,通常通过调用super().__new__
来完成。 - user2357112X()
会调用对象X
的__call__
方法,因为这就是该操作符的作用。实际上,它是type(X).__call__(X)
。 - Mad Physicist