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

问题描述:

怎么可能有一个类的实例是object,没有类是object的子类?这里有一个例子:实例是一个“对象”,但类不是“对象”的子类:这怎么可能?

>>> class OldStyle(): pass 
>>> issubclass(OldStyle, object) 
False 
>>> old_style = OldStyle() 
>>> isinstance(old_style, object) 
True 

在Python 2,是不一样的东西,具体而言,对于老式类,type(obj)is not the same objectobj.__class__。所以这是可能的,因为旧式的类的实例是不同类型(instance)比他们班的实际上是:

>>> 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> 

这新式的类解析:

>>> 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'> 

旧式班级不是一种类型,新式班级是:

>>> isinstance(A, type) 
False 
>>> isinstance(NA, type) 
True 

老风格类被声明为弃用。在Python 3中,只有新风格的类; class A()相当于class A(object),您的代码将在两次检查中产生True

看看这个问题的更多讨论:What is the difference between old style and new style classes in Python?

+0

+1:这是一个非常明确的描述,也是一个很好的观点。谢谢! – EOL 2012-03-14 12:26:20

+0

对于任何人想知道的,'isinstance'是[special-cased](https://github.com/python/cpython/blob/e6a0b5982973e64b9f​​a28e5e3e54eb8c47882780/Objects/abstract.c#L2898)旧式实例和类(例如'PyClass_Check (cls)&& PyInstance_Check(inst)'在C中)。由于没有基于类型的关系,因此它会为'issubclass'检查获取实例的__class__',这也是[特殊的](https://github.com/python/cpython/blob/e6a0b5982973e64b9f​​a28e5e3e54eb8c47882780/Objects /classobject.c#L486)用于旧式类。 – eryksun 2017-06-15 13:04:45

一切都是对象:

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 

注意,这个问题具有本质无关OLD-与新样式类。 isinstance(old_style, object)True仅仅是一个事实的推论,即python中的每个值都是object的一个实例。

+0

您有参考吗? – EOL 2012-03-14 12:22:55

+1

@EOL:[this one](http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html)相当有帮助 – georg 2012-03-14 12:32:26

+1

谢谢。我查看了参考资料,但是我找不到任何关于Python中的所有内容都是* type *'object'这一观点的任何迹象(Python中的“一切都是对象”这一事实并不意味着同样的事实)。 – EOL 2012-03-14 13:48:54

当进行表达式

old_style = OldStyle() 

这意味着你正在实例化对象,其中old_style是类旧式的一个实例。

此外,Python 3.2中都评估为True。