标签:
__metaclass__ = something..
放置元类的位置可以是任意的,python解释器进行查找元类的顺序这篇文章中已经详细说明:“如果Python没有找到__metaclass__,它会继续在Bar(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。”值得注意的是,放置位置带来的区别。
def metafunc(classname,bases,attrs): for key,value in attrs.items(): if isinstance(value,int): attrs[key.upper()]=value attrs.pop(key) print ‘In[%s:From-->%s]‘%(classname,bases) return type(classname,bases,attrs)
函数metafunc是定义好的作为__metaclass__元类属性的函数,其作用便是将要创建的类中的int类型的属性名大写。其实也就是在类创建前“做些事”之后,再利用type创建想要的类。值得注意的是:
1 #此时如果将元类属性放置在module level,发现无任何作用,不知道是不是python版本不同导致 2 __metaclass__ = metafunc 3 class MyClass(object): 4 lower = 123 5 strs = ‘string in MyClass..‘ 6 class MySubClass(MyClass): 7 kid_lower = 456 8 kid_strs = ‘string in MySubClass..‘ 9 #此时若把元类属性放置于父类MyClass或者子类MySubClass中,发现只有放置了__metaclass__属性的类会达到预期的效果 10 class MyClass(object): 11 __metaclass__ = metafunc 12 lower = 123 13 strs = ‘string in MyClass..‘ 14 class MySubClass(MyClass): 15 __metaclass__ = metafunc 16 kid_lower = 456 17 kid_strs = ‘string in MySubClass..‘
In[MyClass:From-->(<type ‘object‘>,)]
放置于子类的结果:
In[MySubClass:From-->(<class ‘__main__.MyClass‘>,)]
class testMetaclass(type): def __new__(cls,name,bases,attrs): for key,value in attrs.items(): if isinstance(value,int): attrs[key.upper()]=value attrs.pop(key) print ‘In[%s:From-->%s]==>testMetaclass‘%(name,bases) return super(testMetaclass,cls).__new__(cls,name,bases,attrs) def __call__(cls,*args): print ‘call metaclass‘ return super(testMetaclass,cls).__call__(*args)
自定义类testMetaclass(一般定义元类的命名可以在类名末尾加上Metaclass :P)作为__metaclass__元类属性,在元类创建类的时候,调用__new__方法,要在创建前“做些事”也是在这个方法中实现。__call__方法是创建的类实例化的时候才会被调用。这个也可以在实例化前“做些事”..:)
#若把__metaclass__属性放置于module level,也是任何作用都没有。。囧。但是把其只放置于父类Myclass中,子类也会被影响;把其只放置于子类中,父类不会被影响。 class MyClass(object): __metaclass__ = testMetaclass lower = 123 strs = ‘string in MyClass..‘ class MySubClass(MyClass): kid_lower = 456 kid_strs = ‘string in MySubClass..‘
【输出:】
1 In[MyClass:From-->(<type ‘object‘>,)]==>testMetaclass 2 In[MySubClass:From-->(<class ‘__main__.MyClass‘>,)]==>testMetaclass
放于子类的结果:
In[MySubClass:From-->(<class ‘__main__.MyClass‘>,)]==>testMetaclass
标签:
原文地址:http://www.cnblogs.com/f00ly/p/5470599.html