我有一个类对象,cls
。我想知道它的元类是什么。我应该怎么做?
(如果我想知道它的父类,我会使用 cls.__mro__
。是否有类似的方法可以获取元类?)
我有一个类对象,cls
。我想知道它的元类是什么。我应该怎么做?
(如果我想知道它的父类,我会使用 cls.__mro__
。是否有类似的方法可以获取元类?)
好的- 那么,一个类的元类只是它自己的 "类型",并且可以通过type(cls)
和其他手段(例如 cls.__class__
)给出。
在Python 3.x中,没有进一步的歧义-因为创建元类的语法只是将其作为类声明语句上的命名参数传递。
然而,在Python 2.x中用于创建元类的语法会产生一个值得注意的副作用。
执行以下操作时:
class A(object):
__metaclass__ = MyMeta
__metaclass__
属性在实际类中设置为该值,即使实际元类是另一个值也是如此。
考虑:
def class_pre_decorator(name, bases, namespace):
# do something with namespace
return type(name, bases, namespace)
这是一个可通过元类声明在Python 2和3中使用的可调用函数-并且是有效的。解析后,在两种情况下实际元类将简单地为type
。然而,在Python 2.x中,cls.__metaclass__
将指向可调用的class_pre_decorator
,即使type(cls)
返回正确的元类type
。(请注意,以这种方式使用可调用函数时,当类进一步派生时它们不会再次使用)
在Python 3中没有办法猜测用于实例化类的实际可调用函数,如果它没有给出其他提示(例如在类上设置属性)表明它被使用:
# 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__
将会引发AttributeError异常。
class_pre_decorator
不是 class A(object)
的元类——在Python 3中定义类的__metaclass__
属性对使用哪个元类没有影响(无论它是什么类型的值,可调用或不可调用)。 - martineau
type(cls)
。 - vaultahtype(myobject)
来获取它。元类只是一个类的类。 - hello world