【问题标题】:How to determine the metaclass of a class?如何确定一个类的元类?
【发布时间】:2017-10-06 19:34:27
【问题描述】:

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

(如果我想知道它的父类,我会做cls.__mro__。有这样的东西来获取元类吗?)

【问题讨论】:

  • type(cls)
  • @Jim IMO 一个好的答案可以解释为什么类对象的类型是创建它的元类。
  • 如果 OP 的问题以实际要求 why 而不是 how 的方式重新格式化,那么请确定@vaultah。按照目前的情况,我个人认为不应该重新开放。如果您仍然认为有必要,请随意这样做。
  • 一切都是python中的对象。类也是对象。每个对象都有一个与之关联的类,您可以通过type(myobject) 获取它。元类只是一个类中的一个类。
  • 类打字有一些具体的事情我认为在 dup 中没有涵盖。问题,即使是这样,询问“查找元类”的人也不会自动搜索“查找对象的类型”——解释这两件事相同的文本属于 this 的答案题。 (这就是我要求重新打开它的原因)

标签: python python-3.x class metaclass


【解决方案1】:

好的 - 所以,一个类的元类只是它自己的“类型”,可以由 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。

【讨论】:

  • 我认为你的最后一个例子不是很清楚。由于在 Python 2 和 3 之间指定元类的语法发生了变化,class_pre_decorator不是class A(object) 的元类——像在 Python 3 中那样定义类 __metaclass__ 属性没有影响关于使用什么元类(无论是什么类型的值,可调用与否,都已给出)。
猜你喜欢
  • 2019-05-30
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
  • 2014-04-20
  • 2019-04-28
  • 1970-01-01
相关资源
最近更新 更多