传统类、新式类和元类

5
在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__。那是另一个完全不同的问题。 - Chris Morgan
@ChrisMorgan,是的,我刚刚意识到了这一点。 - Alcott
2
A是一个新式类,因为“新式类是使用type()构建的”,而且你已经将它的元类设置为type。旧式类使用types.ClassType - jamylak
@jamylak,你可以看到,A没有继承自object,但我仍然在A中使用了__metaclass__,这样可以吗?因为我认为,__metaclass__只能用于继承自object的类,对吗? - Alcott
1
__metaclass__ 在每个类中都被使用。每个类都有一个元类来构造它。 - jamylak
2个回答

5
关于元类的信息,你可以在这里阅读:http://docs.python.org/reference/datamodel.html#customizing-class-creation。通常情况下,元类是用于新式类的。当你编写以下代码时:
class M(type):
    pass

而且您使用:

class C:
    __metaclass__ = M

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


1
关于插槽,您可以在这里阅读http://docs.python.org/release/2.5.2/ref/slots.html,其中一段内容如下:
默认情况下,旧式类和新式类的实例都有一个用于属性存储的字典。
对于新式类,您可以添加__slots__,然后不会创建每个对象的字典。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接