Python元类和对象基类
在阅读了那篇很棒的StackOverflow帖子后,我尝试创建一个模块级的 metaclass:
def metaclass(future_class_name, future_class_parents, future_class_attrs):
print "module.__metaclass__"
future_class_attrs["bar"]="bar"
return type(future_class_name, future_class_parents, future_class_attrs)
__metaclass__=metaclass
class Foo(object):
def __init__(self):
print 'Foo.__init__'
f=Foo()
这段代码不工作(也就是说,“module.metaclass”没有被打印出来),除非我去掉 Foo 的 object
基类。为什么会这样呢?
注意:我使用的是 Python 2.6.1。
2 个回答
2
这个说明文档讲述了Python查找元类的顺序:
合适的元类是根据以下优先级规则来决定的:
- 如果
dict['__metaclass__']
存在,就使用它。- 否则,如果至少有一个基类,就使用它的元类(这会先查找
__class__
属性,如果没找到,就用它的类型)。- 否则,如果存在一个名为
__metaclass__
的全局变量,就使用它。- 否则,就使用旧式的经典元类(
types.ClassType
)。
从上面的内容可以看出,只要有一个基类存在(不管这个基类是什么,即使它最终不继承自object
),就会优先使用模块级的__metaclass__
。
3
从 object 继承会自动带上 type 这个元类。这会覆盖你在模块级别上指定的 __metaclass__。
如果在类级别指定了元类,那么 object 就不会覆盖它:
def metaclass(future_class_name, future_class_parents, future_class_attrs):
print "module.__metaclass__"
future_class_attrs["bar"]="bar"
return type(future_class_name, future_class_parents, future_class_attrs)
class Foo(object):
__metaclass__ = metaclass
def __init__(self):
print 'Foo.__init__'
f=Foo()
可以查看 http://docs.python.org/reference/datamodel.html?highlight=metaclass#customizing-class-creation