实例是一个“对象”,但类不是“对象”的子类:这怎么可能?
问题描述:
怎么可能有一个类的实例是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 object为obj.__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?
答
一切都是对象:
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
的一个实例。
答
当进行表达式
old_style = OldStyle()
这意味着你正在实例化对象,其中old_style是类旧式的一个实例。
此外,Python 3.2中都评估为True。
+1:这是一个非常明确的描述,也是一个很好的观点。谢谢! – EOL 2012-03-14 12:26:20
对于任何人想知道的,'isinstance'是[special-cased](https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects/abstract.c#L2898)旧式实例和类(例如'PyClass_Check (cls)&& PyInstance_Check(inst)'在C中)。由于没有基于类型的关系,因此它会为'issubclass'检查获取实例的__class__',这也是[特殊的](https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects /classobject.c#L486)用于旧式类。 – eryksun 2017-06-15 13:04:45