代码如下:
# metaclass函数defupper(cls_name, cls_parents, cls_attr):""" Make all class attributes uppper case """
attrs = ((name, value) for name, value in cls_attr.items()
ifnot name.startswith('__'))
upper_atts = dict((name.upper(), value) for name, value in attrs)
return type(cls_name, cls_parents, upper_atts)
__metaclass__ = upper #module levelclassFoo:
foo = 1classBar:
bar = 1
此时,Foo类中的的foo属性变成了Foo,Bar类中的的bar属性变成了BAR。如果只需要对某个类增加metaclass属性,则只需要在该类中增加 metaclass = upper。
注意:在python3.5中,不支持这种方式来定论模块metaclass属性。
采用OPP方式增加模块metaclass
一开始开心地以为可以直接采用类似函数的方式来实现模块级metaclass,代码如下:
classUpperAttrMetaclass(type):def__new__(cls, name, bases, dct):
attrs = ((name, value) for name, value in dct.items() ifnot name.startswith('__'))
uppercase_attr = dict((name.upper(), value) for name, value in attrs)
return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)
__metaclass__ = UpperAttrMetaclass
classFoo(object):
foo = 1def__init__(self, foo1):
self.foo1 = foo1
此时还高兴的以为Foo增加了metaclass属性,将foo属性变成了FOO; 而实际上并没有。多么痛的领悟啊!那怎么办呢?经过各种查,找到了一个解决方法,可以采用继承的方式来实现metaclass属性,而且这各方式还可以灵活的选择所要继承的metaclass。
代码如下:
classUpperAttrMetaclass(type):def__new__(cls, name, bases, dct):
attrs = ((name, value) for name, value in dct.items() ifnot name.startswith('__'))
uppercase_attr = dict((name.upper(), value) for name, value in attrs)
return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)
classUp(object):
__metaclass__ = UpperAttrMetaclass
classFoo(Up):
foo = 1def__init__(self, foo1):
self.foo1 = foo1
该方法可以解决python3.5中不支持 函数式metaclass 的问题
也许还有更好的方法,望大神们指正与探讨!!!