Inheritance of metaclass
在这个解释Python中元类的众所周知的答案中。它提到,
但事实上,我在python中尝试过:
1 2 3 4 5 6 7 8 9 10 11 12 | class Meta1(type): def __new__(cls, clsname, bases, dct): print"Using Meta1" return type.__new__(cls, clsname, bases, dct) #"Using Meta1" printed class Foo1: __metaclass__ = Meta1 #"Using Meta1" printed class Bar1(Foo1): pass |
如预期,
但在下面的示例中,当返回
1 2 3 4 5 6 7 8 9 10 11 12 | class Meta2(type): def __new__(cls, clsname, bases, dct): print"Using Meta2" return type(clsname, bases, dct) #"Using Meta2" printed class Foo2: __metaclass__ = Meta2 # Nothing printed class Bar2(Foo2): pass |
号
检查
1 2 3 4 5 6 7 8 9 | print Foo1.__metaclass__ # <class '__main__.Meta1'> print Bar1.__metaclass__ # <class '__main__.Meta1'> print Foo2.__metaclass__ # <class '__main__.Meta2'> print Bar2.__metaclass__ # <class '__main__.Meta2'> print Foo1.__class__ # <class '__main__.Meta1'> print Bar1.__class__ # <class '__main__.Meta1'> print Foo2.__class__ # <type 'type'> print Bar2.__class__ # <type 'type'> |
综上所述:
由
这些观察使我对
我的猜测是:
当直接将一个类(如
当子类在定义时没有显式设置
我的猜测正确吗?Python如何处理元类的继承?
你在猜测很多,而python的极简主义和"特殊情况不足以打破规则。"指令,使其更容易理解。
在python2中,在类创建时使用类体中的
所以让我们检查一下情况,比如:
1 2 3 4 5 | class A(object): __metaclass__ = MetaA class B(A): pass |
创建b时根本不使用该
举例说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | In [1]: class M(type): pass In [2]: class A(object): __metaclass__ = M In [3]: print"class: {}, metaclass_attr: {}, metaclass_in_dict: {}, type: {}".format(A.__class__, A.__metaclass__, A.__dict__.get("__metaclass__"), type(A)) class: <class '__main__.M'>, metaclass_attr: <class '__main__.M'>, metaclass_in_dict: <class '__main__.M'>, type: <class '__main__.M'> In [4]: class B(A): pass In [5]: print"class: {}, metaclass_attr: {}, metaclass_in_dict: {}, type: {}".format(B.__class__, B.__metaclass__, B.__dict__.get("__metaclass__"), type(B)) class: <class '__main__.M'>, metaclass_attr: <class '__main__.M'>, metaclass_in_dict: None, type: <class '__main__.M'> In [6]: A.__metaclass__ = type In [8]: class C(A): pass In [9]: print"class: {}, metaclass_attr: {}, metaclass_in_dict: {}, type: {}".format(C.__class__, C.__metaclass__, C.__dict__.get("__metaclass__"), type(C)) class: <class '__main__.M'>, metaclass_attr: <type 'type'>, metaclass_in_dict: None, type: <class '__main__.M'> |
号
此外,如果您试图通过调用
1 2 3 4 | In [11]: D = type("D", (object,), {"__metaclass__": M}) In [12]: type(D) type |
总结到目前为止:python 2中的
python3都摆脱了这个奇怪的"
现在,到引起您怀疑的第二部分:如果在元类的
所以,找出区别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class M1(type): def __new__(metacls, name, bases, attrs): cls = type.__new__(metacls, name, bases, attrs) # cls now is an instance of"M1" ... return cls class M2(type): def __new__(metacls, name, bases, attrs): cls = type(cls, name, bases, attrs) # Type does not"know" it was called from within"M2" # cls is an ordinary instance of"type" ... return cls |
。
在交互提示中可以看到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | In [13]: class M2(type): ....: def __new__(metacls, name, bases, attrs): ....: return type(name, bases, attrs) ....: In [14]: class A(M2): pass In [15]: type(A) Out[15]: type In [16]: class A(M2): __metaclass__ = M2 In [17]: A.__class__, A.__metaclass__ Out[17]: (type, __main__.M2) |
(请注意,元类