class Meta1(type):
def __new__(meta, classname, supers, classdict):
print('In Meta1 new: ', classname, supers, classdict, sep='\n...')
return type.__new__(meta, classname, supers, classdict)
def __init__(Class, classname, supers, classdict):
print('In Meta1 init:', classname, supers, classdict, sep='\n...')
def __call__(meta, classname, supers, classdict):
print('In Meta1 call: ', classname, supers, classdict, sep='\n...')
return type.__call__(meta, classname, supers, classdict)
class Meta2(type, metaclass=Meta1):
def __new__(meta, classname, supers, classdict):
print('In Meta2 new: ', classname, supers, classdict, sep='\n...')
return type.__new__(meta, classname, supers, classdict)
def __init__(Class, classname, supers, classdict):
print('In Meta2 init:', classname, supers, classdict, sep='\n...')
print('...init class object:', list(Class.__dict__.keys()))
def __call__(meta):
print('In Meta2 call')
return type.__call__(meta)
class Eggs:
pass
print('making class')
class Spam(Eggs, metaclass=Meta2):
data = 1
def meth(self, arg):
pass
print('making instance')
X = Spam()
print('data:', X.data)
上面代码输出如下:
In Meta1 new:
...Meta2
...(,)
...{'__module__': '__main__', '__qualname__': 'Meta2', '__new__': , '__init__': , '__call__': }
In Meta1 init:
...Meta2
...(,)
...{'__module__': '__main__', '__qualname__': 'Meta2', '__new__': , '__init__': , '__call__': }
making class
In Meta1 call:
...Spam
...(,)
...{'__module__': '__main__', '__qualname__': 'Spam', 'data': 1, 'meth': }
In Meta2 new:
...Spam
...(,)
...{'__module__': '__main__', '__qualname__': 'Spam', 'data': 1, 'meth': }
In Meta2 init:
...Spam
...(,)
...{'__module__': '__main__', '__qualname__': 'Spam', 'data': 1, 'meth': }
...init class object: ['__module__', 'data', 'meth', '__doc__']
making instance
In Meta2 call
data: 1
我的问题如下:
1、Spam 的元类是 Meta2,Meta2 的元类是 Meta1。为何执行“ class Spam(Eggs, metaclass=Meta2)”定义 Spam 的时候,在对 Meta2 执行 new 和 init 做初始化之前,要先去执行 Meta1 的 call ?
2、执行“ X = Spam()”时,Meta1 和 Meta2 都定义了 call 方法的前提下,为何不是执行 Meta1 的 call,而是去执行 Meta2 的 call ?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.