This applies to old-style objects (inheriting from nothing). Such objects do not have the __class__
property. I think they do it in such a way as to prevent mistakes. Example for 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__'
See additional information:
Note: These lines from cpython were last modified in 2008 ( commit ), so it really looks like compatibility, or they just forgot about it.
source share