旧式类、新式类和元类
Posted
技术标签:
【中文标题】旧式类、新式类和元类【英文标题】: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
为什么A
和B
的实例都是object
的实例?
如果B
是object
的一个实例,那么type(B)
就不会是classobj
,对吧?
【问题讨论】:
您不应该将__slots__
放在这个问题中。这完全是另一个问题。
@ChrisMorgan,是的,我刚刚意识到这一点。
A 是一个新样式类,因为 '新样式类是使用 type()' 构造的,并且您已将它的元类设置为 type
。旧式类使用types.ClassType
@jamylak,如你所见,A
没有继承自object
,但我仍然在A
中使用__metaclass__
,这样可以吗?因为我想,__metaclass__
只能用于继承自 object
的类,对吧?
__metaclass__
用于每个类。每个类都有一个构建它的元类。
【参考方案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__
,则不会创建每个对象的字典。
【讨论】:
以上是关于旧式类、新式类和元类的主要内容,如果未能解决你的问题,请参考以下文章