如何确定class的metaclass?
How to determine the metaclass of a class?
我有一个 class 对象,cls
。我想知道它的 metaclass。我该怎么做?
(如果我想知道它的父 classes,我会做 cls.__mro__
。有这样的东西来获取元 class 吗?)
好的 - 所以,一个 class 的元 class 只是它自己的 "type",可以通过
type(cls)
和其他方式如 cls.__class__
.
在 Python 3.x 中没有进一步的歧义——因为创建元 class 的语法只是将其作为命名参数传递给 class 声明语句反正。
但是,用于在 Python 2.x 中创建元 class 的语法会产生一个值得注意的副作用。
在做
class A(object):
__metaclass__ = MyMeta
__metaclass__
属性在实际 class、 中设置为该值,即使实际元class 是另一个 。
考虑:
def class_pre_decorator(name, bases, namespace):
# do something with namespace
return type(name, bases, namespace)
这是一个可以在 Python 2 和 3 的元class 声明中使用的可调用对象 - 它是有效的。解析后,两种情况下的实际 metaclass 将只是 type
。但是,在Python2.x中,cls.__metaclass__
会指向callableclass_pre_decorator
,即使是toughtype(cls)
returnstype
,也就是正确的 metaclass。(请注意,以这种方式使用可调用对象,当 class 被进一步子 classed 时,它们将不会被再次使用)
在 Python 3 中没有办法猜测实际用于实例化 class 的可调用对象,如果它没有给出其他提示(比如在 class 上设置属性)它被使用:
# 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 对象,cls
。我想知道它的 metaclass。我该怎么做?
(如果我想知道它的父 classes,我会做 cls.__mro__
。有这样的东西来获取元 class 吗?)
好的 - 所以,一个 class 的元 class 只是它自己的 "type",可以通过
type(cls)
和其他方式如 cls.__class__
.
在 Python 3.x 中没有进一步的歧义——因为创建元 class 的语法只是将其作为命名参数传递给 class 声明语句反正。
但是,用于在 Python 2.x 中创建元 class 的语法会产生一个值得注意的副作用。
在做
class A(object):
__metaclass__ = MyMeta
__metaclass__
属性在实际 class、 中设置为该值,即使实际元class 是另一个 。
考虑:
def class_pre_decorator(name, bases, namespace):
# do something with namespace
return type(name, bases, namespace)
这是一个可以在 Python 2 和 3 的元class 声明中使用的可调用对象 - 它是有效的。解析后,两种情况下的实际 metaclass 将只是 type
。但是,在Python2.x中,cls.__metaclass__
会指向callableclass_pre_decorator
,即使是toughtype(cls)
returnstype
,也就是正确的 metaclass。(请注意,以这种方式使用可调用对象,当 class 被进一步子 classed 时,它们将不会被再次使用)
在 Python 3 中没有办法猜测实际用于实例化 class 的可调用对象,如果它没有给出其他提示(比如在 class 上设置属性)它被使用:
# 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。