Search code examples
python-2.7python-3.xtypesnew-style-class

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


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.


Solution

  • 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