type(instance) 和 instance.__class__ 可能不同,即使使用 new-style classes,正如 Guido van Rossum 在PEP 3119 中提到的那样:
另外,isinstance(x, B) 等价于 issubclass(x.__class__, B) or issubclass(type(x), B)。 (type(x) 和 x.__class__ 可能不是同一个对象,例如当 x 是代理对象时。)
type(instance)
object 实例的真实类存储在实例上的 __class__ 槽 中(即在实例布局中的固定偏移处)。只能通过数据描述符vars(object)['__class__']访问(其方法__get__允许属性检索,其方法__set__允许属性赋值,其方法__delete__禁止属性删除),或者等效地通过内置函数访问type(其单参数形式允许属性检索):
>>> class A: pass
...
>>> a = A()
>>> vars(object)['__class__'].__get__(a)
<class '__main__.A'>
>>> type(a)
<class '__main__.A'>
>>> class B: pass
...
>>> vars(object)['__class__'].__set__(a, B)
>>> vars(object)['__class__'].__get__(a)
<class '__main__.B'>
>>> type(a)
<class '__main__.B'>
>>> vars(object)['__class__'].__delete__(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't delete __class__ attribute
instance.__class__
所以如果一个实例没有覆盖数据描述符vars(object)['__class__'](带有类属性),instance.__class__会访问instance的真实类(通过数据描述符):
>>> class A: pass
...
>>> a = A()
>>> a.__class__
<class '__main__.A'>
>>> type(a)
<class '__main__.A'>
>>> class B: pass
...
>>> a.__class__ = B
>>> a.__class__
<class '__main__.B'>
>>> type(a)
<class '__main__.B'>
>>> del a.__class__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't delete __class__ attribute
但是如果一个实例覆盖了数据描述符vars(object)['__class__'](带有类属性),instance.__class__可能无法访问instance的真实类(所以instance作为另一个类的实例出现):
>>> class A: __class__ = int
...
>>> a = A()
>>> a.__class__
<class 'int'>
>>> type(a)
<class '__main__.A'>
>>> vars(a).update({'__class__': str})
>>> a.__class__ # the class attribute is not a data descriptor so is overridden
<class 'str'>
>>> type(a)
<class '__main__.A'>