Python中元类的执行优先次序

来源:互联网 发布:mysql,书 编辑:程序博客网 时间:2024/06/07 01:50

Python元类的执行顺序测试

在stackoverflow上关于元类的高票答案中提到了Python中的元类的优先次序为

  1. 是否在Foo中有__metaclass__属性?如果有,在内存中通过使用__metaclass__中指定的和Foo这个名字创建类对象。
  2. 如果找不到__metaclass__,Python将会使用Bar(Foo的第一个父类)的metaclass(可能是默认的type)来创建类对象。
  3. 如果Python找不到__metaclass__,Python将会在模块层次寻找__metaclass__,并且尝试做相同的事情(仅仅对没有继承任何类的类,基本上都是old-style classes 基本上可以认为是没有继承object的类,super就不适用于old-style classes)

现在测试如下:

class MetaClassTest1class(type):    def __new__(cls, clsname, bases, dct):        dct['test'] = 1        return super(MetaClassTest1class, cls).__new__(cls, clsname, bases, dct)class MetaClassTest2class(type):    def __new__(cls, clsname, bases, dct):        dct['test'] = 2        return super(MetaClassTest2class, cls).__new__(cls, clsname, bases, dct)__metaclass__ = MetaClassTest1classclass Foo():    __metaclass__ = MetaClassTest2class    passf = Foo()print f.test

输出为2,所以会优先调用自己的__metaclass__

对于2,

class MetaClassTest1class(type):    def __new__(cls, clsname, bases, dct):        dct['test'] = 1        return super(MetaClassTest1class, cls).__new__(cls, clsname, bases, dct)class MetaClassTest2class(type):    def __new__(cls, clsname, bases, dct):        dct['test'] = 2        return super(MetaClassTest2class, cls).__new__(cls, clsname, bases, dct)class MetaClassTest3class(MetaClassTest2class):    def __new__(cls, clsname, bases, dct):        dct['test'] = 3        return super(MetaClassTest3class, cls).__new__(cls, clsname, bases, dct)__metaclass__ = MetaClassTest1classclass Foo():    __metaclass__ = MetaClassTest2class    passclass FooChild(Foo):    passf = Foo()print f.test

输出为2,所以在自己没有__metalcass__的情况下,看起来会使用父类的__metaclass__

对于3,

class MetaClassTest1class(type):    def __new__(cls, clsname, bases, dct):        dct['test'] = 1        return super(MetaClassTest1class, cls).__new__(cls, clsname, bases, dct)__metaclass__ = MetaClassTest1classclass Foo():    passclass FooChild(Foo):    passf = Foo()print f.test

输出为1,所以可以看到,在自身没有元类,父类没有元类的时候会使用模块中的元类。

0 0
原创粉丝点击