为什么 isinstance(nonnewstyle, object) return 在 Python 2.X 中为真?

Why does isinstance(nonnewstyle, object) return true in Python 2.X?

我正在阅读一本关于 Python 的教科书,它涵盖了新式 class 的差异。在解释器中观察 Python 2.X 中的以下代码,它使用 classic classes:

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

(要使用新式 classes,必须显式派生自 2.X 中的对象 class)

那么不从对象 class 派生的对象(如 classic classes 中的情况)如何成为对象的实例? 3.X 和 2.X 的幕后发生了什么?

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

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

一切都是object的实例。所以 isinstance(C, object)isinstance(x, object) 将永远是 True.

Python中的一切都是object的实例,包括object本身:

>>> isinstance(object, object)
True

那是因为 type.__instancecheck__ hook returns Trueobject 中为 self 传递时,无论其他参数是什么(记住特殊方法是查看 type(something),而不是 something 本身,并手动传入 self

如果您想测试旧式 classes,一个更有用的测试是 class 是 type 的实例,还是 [=38= object 的 ]subclass:

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

这些测试中的任何一个都适用于新式 classes:

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

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

的实例
>>> isinstance(X, InstanceType)
True

X 是旧式 class C 的旧式实例,它不是 object.

的子class

然而,所有对象,甚至旧式实例,都是某种类型的实例(a.k.a。新式class)。所有老式实例的类型都是types.InstanceType;加上types.ClassType,老式classes的类型,这两个类型负责老式class系统的实现。

types.InstanceTypeobject 的子class,所有新式 class 也是如此。 isinstance(X, object) returns 正确不是因为 X 的旧式 class 继承自 object,而是因为其新式 class 继承。