关于python:实例是一个”对象”,但是类不是”对象”的子类:这怎么可能?

Instance is an “object”, but class is not a subclass of “object”: how is this possible?

如果一个类不是object的子类,怎么可能有一个object类的实例呢?下面是一个例子:

1
2
3
4
5
6
>>> class OldStyle(): pass
>>> issubclass(OldStyle, object)
False
>>> old_style = OldStyle()
>>> isinstance(old_style, object)
True

在python 2中,类型和类是不同的,特别是对于旧式类,type(obj)obj.__class__不是同一个对象。因此,这是可能的,因为旧样式类的实例实际上与它们的类不同(instance):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> class A(): pass
>>> class B(A): pass
>>> b = B()

>>> assert b.__class__ is B
>>> issubclass(b.__class__, A) # same as issubclass(B, A)
True
>>> issubclass(type(b), A)
False

>>> type(b)
<type 'instance'>
>>> b.__class__
<class __main__.B at 0x10043aa10>

这是在新样式类中解决的:

1
2
3
4
5
6
7
8
9
>>> class NA(object): pass
>>> class NB(NA): pass
>>> nb = NB()
>>> issubclass(type(nb), NA)
True
>>> type(nb)
<class '__main__.NB'>
>>> nb.__class__
<class '__main__.NB'>

旧样式类不是类型,新样式类是:

1
2
3
4
>>> isinstance(A, type)
False
>>> isinstance(NA, type)
True

旧样式类被声明为已弃用。在python 3中,只有新的类;class A()相当于class A(object),您的代码在两个检查中都会产生True

请看一下这个问题,了解更多的讨论:在Python中,旧样式类和新样式类之间的区别是什么?


一切都是一个物体:

1
2
3
4
5
6
isinstance(123, object) # True
isinstance("green cheese", object) # True
isinstance(someOldClassObject, object) # True
isinstance(someNewClassObject, object) # True
isinstance(object, object) # True
isinstance(None, object) # True

请注意,这个问题本质上与旧样式类和新样式类无关。isinstance(old_style, object)True的结果,只是python中的每个值都是object的一个实例的推论。


当你做这个表达的时候

1
   old_style = OldStyle()

这意味着您正在实例化对象,哪个旧的_样式是类oldStyle的实例。

而且,在python 3.2中,这两个值都为true。