Python 如何确定类的元类?

Python 如何确定类的元类?,python,python-3.x,class,metaclass,Python,Python 3.x,Class,Metaclass,我有一个类对象,cls。我想知道它的元类。我该怎么做 (如果我想知道它的父类,我会做cls.\uuu mro\uuuu。是否有类似的东西来获取元类?好的-因此,类的元类只是它自己的“类型”,可以通过 类型(cls)和其他方式,如cls.\uuuuuu class\uuuuuu 在Python3.x中没有进一步的歧义——因为创建元类的语法只是在类声明语句中将其作为命名参数传递 然而,在Python2.x中用于创建元类的语法产生了一个值得注意的副作用 一做 class A(object):

我有一个类对象,
cls
。我想知道它的元类。我该怎么做


(如果我想知道它的父类,我会做
cls.\uuu mro\uuuu
。是否有类似的东西来获取元类?

好的-因此,类的元类只是它自己的“类型”,可以通过
类型(cls)
和其他方式,如
cls.\uuuuuu class\uuuuuu

在Python3.x中没有进一步的歧义——因为创建元类的语法只是在类声明语句中将其作为命名参数传递

然而,在Python2.x中用于创建元类的语法产生了一个值得注意的副作用

一做

class A(object):
    __metaclass__ = MyMeta
\uuuuuuuuu元类
属性在实际类中设置为该值,即使实际元类是另一个元类

考虑:

def class_pre_decorator(name, bases, namespace):
     # do something with namespace
     return type(name, bases, namespace)
这是一个可调用函数,可以在Python2和Python3的元类声明中使用,并且是有效的。解析后,两种情况下的实际元类都将是
类型
。然而,在Python2.x中,
cls.\uuuuu元类\uuuuuuu
将指向可调用的
class\u pre\u decorator
,甚至是难处理的
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>

尝试读取
A.\uuuu元类\uuuuu
只会引发AttributeError

只是
type(cls)
@Jim IMO一个好的答案可以解释为什么类对象的类型是它创建时使用的元类。如果OP的问题以一种实际询问为什么而不是如何的方式重新格式化,那么肯定@vaultah。就目前的情况而言,我个人认为它不应该重新开放。如果您仍然相信这是有保证的,那么您可以随意这样做。在python中,一切都是一个对象。类也是对象。每个对象都有一个与之关联的类,您可以通过
类型(myobject)
获得它。元类只是一个类的一个类。对于类类型,我认为dup中没有涉及到一些特定的内容。问题,即使是这样,询问“查找元类”的人也不会自动搜索“查找对象的类型”——解释这两件事相同的文本属于这个问题的答案。(这就是我要求它重新开放的原因)我认为你的最后一个例子不是很清楚。由于在Python2和Python3之间指定元类的语法发生了变化,
class\u pre\u decorator
不是
class a(object)
的元类-像Python3中那样定义class
\uuuuuuuuuuuuuuuuuuuuuuuuuuu元类
属性对使用什么元类没有影响(不管是哪种类型的值,不管是否可调用,它都是给定的)。
# Python 3
class A(metaclass=class_pre_decorator):
    pass