为什么isinstance(nonnewstyle,object)在Python 2.X中返回true?

时间:2017-07-12 21:00:40

标签: python-2.7 python-3.x types new-style-class

我正在阅读有关Python的教科书,它涵盖了新式的课堂差异。在解释器中观察Python 2.X中的以下代码,它使用经典类:

class C: pass
X = C()
isinstance(X, object) #returns true
isinstance(C, object) #returns true

(要使用新式类,必须明确地从2.X中的对象类派生)

那么如何从对象类派生的对象(如经典类中的情况)是对象的实例?在3.X和2.X的情况下幕后发生了什么?

至于这是否是一个重复的问题:我已经知道一切在技术上都是一个对象,我想知道如何在python本身的设计中明确处理差异,而不是将isinstance的结果视为理所当然。

3 个答案:

答案 0 :(得分:0)

您可能会将isinstanceissubclass混淆。旧样式类不会从object 派生,这意味着issubclass(C, object)的结果将是False。另一方面,新样式类始终包含object(直接或间接)作为基类。

所有内容都是object的实例。因此,isinstance(C, object)isinstance(x, object)始终为True

答案 1 :(得分:0)

Python中的

一切object的一个实例,包括object本身:

>>> isinstance(object, object)
True

那是因为type.__instancecheck__ hook在传递True object时返回self,无论其他参数是什么(请记住在{{1}上查找特殊方法}},而不是type(something)本身,并且手动传递something

如果你想测试旧式的类,那么一个更有用的测试是,如果该类是self的实例,或type子类

object

对于新式类,这些测试都是正确的:

>>> isinstance(C, type)
False
>>> issubclass(C, object)
False

例如,测试它们是types.InstanceType的实例:

>>> class Newstyle(object): pass
...
>>> isinstance(Newstyle, type)
True
>>> issubclass(Newstyle, object)
True

答案 2 :(得分:0)

X是旧式C类的旧式实例,它不是object的子类。

但是,所有对象,甚至是旧式实例,都是某种类型的实例(a.k.a。新式类)。所有旧式实例的类型为types.InstanceType;与types.ClassType一起,旧式类的类型,这两种类型负责旧式类系统的实现。

types.InstanceTypeobject的子类,所有新式类都是如此。 isinstance(X, object)返回true不是因为X的旧式类继承自object,而是因为它的新式类。