Why the metaclass definition changed the mro of classic class?
根据方法分辨率顺序:
Classic classes used a simple MRO scheme: when looking up a method,
base classes were searched using a simple depth-first left-to-right
scheme.
号
这可以在python 2.6中验证。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | In [1]: import sys In [2]: sys.version Out[2]: '2.6.6 (r266:84292, Jul 23 2015, 15:22:56) [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)]' In [3]: class D: def f(self): return 'D' class B(D): pass class C(D): def f(self): return 'C' class A(B, C): pass ...: In [4]: A().f() Out[4]: 'D' |
但是,如果我定义了一个元类,那么在python 2.7.12中得到了不同的结果:
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 | Python 2.7.12 (default, Nov 19 2016, 06:48:10) Type"copyright","credits" or"license" for more information. IPython 5.4.0 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: class D: # Note: Old-style ...: def f(self): return"D.f()" ...: class B(D): pass ...: class C(D): ...: def f(self): return"C.f()" ...: class A(B, C): pass ...: In [2]: A().f() Out[2]: 'D.f()' # It works as expected. In [3]: class __metaclass__(type): ...: "All classes are metamagically modified to be nicely printed" ...: __repr__ = lambda cls: cls.__name__ ...: In [4]: class D: # Note: Old-style ...: def f(self): return"D.f()" ...: class B(D): pass ...: class C(D): ...: def f(self): return"C.f()" ...: class A(B, C): pass ...: In [5]: A().f() Out[5]: 'C.f()' # WTF?? |
号
元类只适用于新样式的类,并且通过在类体中有一个名为
1 2 3 4 5 6 7 8 9 10 | class J: pass class K(object): pass class L: __metaclass__ = type type(J) # <type 'classobj'> type(K) # <type 'type'> type(L) # <type 'type'> |
因此,在您的示例中发生的事情似乎是,由于词汇/静态作用域规则,当第二次执行类
您可能不应该命名一个元类
1 2 | class D: __metaclass__ = PrettyPrintClassRepr |
号