好吧,一个类的元类就是它自己的"类型",可以由
在Python 3中.没有进一步的歧义——因为创建元类的语法只是在类声明语句中将其作为命名参数传递.
然而,在Python2中用于创建元类的语法是错误的.x产生了一个值得注意的副作用.
一做
class A(object):
__metaclass__ = MyMeta
__metaclass__
属性在实际类even if the actual metaclass is another one中设置为该值.
考虑:
def class_pre_decorator(name, bases, namespace):
# do something with namespace
return type(name, bases, namespace)
这是一个可以在Python2和Python3的元类声明中使用的可调用函数,它是有效的.解析后,两种情况下的实际元类都将是type
.然而,在Python 2中.x、 cls.__metaclass__
将指向可调用的class_pre_decorator
,甚至tough type(cls)
返回type
,这是正确的元类.(请注意,以这种方式使用可调用项,当类进一步子类化时,它们不会被再次使用)
在Python3中,如果一个类没有给出其他使用该类的提示(比如在该类上设置属性),就无法猜测实际用于实例化该类的可调用项:
# python 2
class A(object):
__metaclass__ = class_pre_decorator
在控制台上:
In [8]: type(A)
Out[8]: type
In [9]: A.__metaclass__
Out[9]: <unbound method A.class_pre_decorator>
和
# Python 3
class A(metaclass=class_pre_decorator):
pass
试着读A.__metaclass__
只会引起一个属性错误.