什么时候类型(实例)不是实例.__ class__?

时间:2017-02-22 07:18:18

标签: python python-3.x types

Python具有内置函数type,每个实例也具有__class__属性。我一般认为他们回归了同样的事情。甚至两者的文档都相似:

  

instance.__class__

     

类实例所属的类。

  

type(object)

     

使用一个参数,返回对象的类型。

然而,在abc.ABCMeta.__instancecheck__中,检查它们是否相同(稍微缩短):

subclass = instance.__class__
subtype = type(instance)
if subtype is subclass:

什么时候不是这样? type(instance)何时与instance.__class__不一样?

2 个答案:

答案 0 :(得分:3)

正如new-style classes中Guido所述,

type(instance)instance.__class__甚至可能与PEP 3119有所不同:

  

此外,isinstance(x, B)等效于issubclass(x.__class__, B) or issubclass(type(x), B)。 (可能type(x)x.__class__不是同一对象,例如x是代理对象时。)

例如:

class A:
    pass

class B:
    __class__ = A

b = B()
print(type(b))      # prints <class '__main__.B'>
print(b.__class__)  # prints <class '__main__.A'>

答案 1 :(得分:2)

旧样式对象(从无到有继承)就是这种情况。此类对象没有__class__属性。我认为他们这样做是为了防止错误。 Python 2.7的示例:

class A:
    pass

class B(object):
    pass

a = A()
b = B()

print(dir(a)) # ['__doc__', '__module__']
print(dir(b)) # ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

print(b.__class__) # <class '__main__.B'>
print(type(b))     # <class '__main__.B'>

#####################
# The intersting part
print(a.__class__) # __main__.A
print(type(a))     # <type 'instance'>


print(B.__class__) # <type 'type'>
print(type(B))     # <type 'type'>

print(type(A))      # <type 'classobj'>
#print(A.__class__) # AttributeError: class A has no attribute '__class__'

有关详细信息,请参阅此处:

注意:来自cpython的给定行在2008年上次更改(commit),所以它似乎是兼容性的东西,或者他们只是忘了它。