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

741 Views Asked by At

I am reading a textbook on Python and it covers new-style class differences. Observe the following code in Python 2.X in the interpreter, which uses classic classes:

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

(To use new-style classes, one must explicitly derive from the object class in 2.X)

So how can an object that does not derive (as is the case in classic classes) from the object class be an instance of object? What is going on behind the scenes in the case of 3.X and 2.X?

As for whether this is a duplicate question: I already knew that everything was technically an object, I was wondering how the discrepancy is handled explicitly in the design of python itself, rather than taking the results of isinstance for granted.

3

There are 3 best solutions below

3
On BEST ANSWER

Everything in Python is an instance of object, including object itself:

>>> isinstance(object, object)
True

That's because the type.__instancecheck__ hook returns True when passed in object for self, no matter what the other argument (remember that special methods are looked up on type(something), not on something itself, and have self passed in manually).

If you want to test for old-style classes, a far more useful test is if the class is an instance of type, or a subclass of object:

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

Either of these tests is true for new-style classes:

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

For instances, test wether they are an instance of types.InstanceType:

>>> isinstance(X, InstanceType)
True
0
On

X is an old-style instance of the old-style class C, which is not a subclass of object.

However, all objects, even old-style instances, are instances of some type (a.k.a. new-style class). The type of all old-style instances is types.InstanceType; together with types.ClassType, the type of old-style classes, these two types are responsible for the implementation of the old-style class system.

types.InstanceType is a subclass of object, as are all new-style classes. isinstance(X, object) returns true not because X's old-style class inherits from object, but because its new-style class does.

0
On

You are probably confusing isinstance with issubclass. Old style classes don't derive from object meaning that the result of issubclass(C, object) will be False. New style classes, on the other hand, always contain object (directly or indirectly) as a base class.

Everything is an instance of object. So doing isinstance(C, object) or isinstance(x, object) will always be True.