深刻理解Python中的元类(metaclass)
PEP 3115 – Metaclasses in Python 3000
第一篇文章中我执行后有错误的代码是这一段:
def upper_attr(future_class_name, future_class_parents, future_class_attr):
'''返回一个类对象,将属性都转为大写形式'''
# 选择所有不以'__'开头的属性
attrs = ((name, value) for name, value in future_class_attr.items() \
if not name.startswith('__'))
# 将它们转为大写形式
uppercase_attr = dict((name.upper(), value) for name, value in attrs)
# 通过'type'来做类对象的创建
return type(future_class_name, future_class_parents, uppercase_attr)
__metaclass__ = upper_attr # 这会作用到这个模块中的所有类
class Foo(object):
#__metaclass__=upper_attr
# 我们也可以只在这里定义__metaclass__,这样就只会作用于这个类中
bar = 'bip'
print hasattr(Foo, 'bar')
# 输出: False
print hasattr(Foo, 'BAR')
# 输出:True
f = Foo()
print f.BAR
注意python3中使用metaclass的语法如下:
class Foo(object,metaclass=upper_attr):
bar = 'bip'
另外在python2.7中__metaclass__不应该定义为全局的,应该放到类的里面去,像下面这样:
class Foo(object):
#__metaclass__=upper_attr
# 我们也可以只在这里定义__metaclass__,这样就只会作用于这个类中
bar = 'bip'
另外在python2.7中改成下面的形式也可以正确运行,使用全局的__metaclass__变量,然后去掉Foo()括号中的object:
__metaclass__ = upper_attr # 这会作用到这个模块中的所有类
class Foo():
#__metaclass__=upper_attr
# 我们也可以只在这里定义__metaclass__,这样就只会作用于这个类中
bar = 'bip'