1

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.

user3751940
  • 123
  • 4
  • 1
    **Everything** is an object. `isinstance(object, object)` is true too. – Martijn Pieters Jul 12 '17 at 21:03
  • A more useful check would be `isinstance(C, type)`, or `issubclass(C, object)`. – jonrsharpe Jul 12 '17 at 21:03
  • Possible duplicate of [Instance is an "object", but class is not a subclass of "object": how is this possible?](https://stackoverflow.com/questions/9699591/instance-is-an-object-but-class-is-not-a-subclass-of-object-how-is-this-po) – MSeifert Jul 12 '17 at 22:25

3 Answers3

0

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.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
0

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
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

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.

user2357112
  • 260,549
  • 28
  • 431
  • 505