【问题标题】:Old-style classes, new-style classes and metaclasses旧式类、新式类和元类
【发布时间】:2012-05-16 17:09:18
【问题描述】:

在 Python 2.x 中,所有新样式的类都隐式或显式地继承自 object。然后看看这个:

>>> class M(type):
...     pass
...
>>> class A:
...     __metaclass__ = M
...
>>> class B:
...     pass
...
>>> a = A()
>>> b = B()
>>> type(A)
<class '__main__.M'>
>>> type(a)
<class '__main__.A'>

这是否意味着A 是一个新式类?但是A 无论如何都不会继承自object,对吧?

>>> type(B)
<class 'classobj'>
>>> type(b)
<type 'instance'>

好的,B 是经典课程,不是吗?

>>> isinstance(A, object)
True
>>> isinstance(B, object)
True

为什么AB 的实例都是object 的实例?

如果Bobject 的一个实例,那么type(B) 就不会是classobj,对吧?

【问题讨论】:

  • 您不应该将__slots__ 放在这个问题中。这完全是另一个问题。
  • @ChrisMorgan,是的,我刚刚意识到这一点。
  • A 是一个新样式类,因为 '新样式类是使用 type()' 构造的,并且您已将它的元类设置为 type。旧式类使用types.ClassType
  • @jamylak,如你所见,A 没有继承自object,但我仍然在A 中使用__metaclass__,这样可以吗?因为我想,__metaclass__ 只能用于继承自 object 的类,对吧?
  • __metaclass__ 用于每个类。每个类都有一个构建它的元类。

标签: python class metaclass new-style-class


【解决方案1】:

关于元类,您可以在此处阅读:http://docs.python.org/reference/datamodel.html#customizing-class-creation。通常,元类旨在与新样式类一起使用。当你写:

class M(type):
    pass

你使用:

class C:
    __metaclass__ = M

您将创建一个新样式对象,因为定义了 M 的方式(默认实现使用type 来创建一个新样式类)。您始终可以实现自己的元类,该元类将使用 types.ClassType 创建旧式类。

【讨论】:

    【解决方案2】:

    关于插槽你可以在这里阅读http://docs.python.org/release/2.5.2/ref/slots.html,一个片段:

    默认情况下,新旧类的实例都有一个用于属性存储的字典。

    对于新式类,您可以添加__slots__,则不会创建每个对象的字典。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-28
      • 2023-03-10
      • 2016-04-22
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多