== Understanding _isinstance()_ on Python classes Suppose that you have: class A(object): pass class B(A): pass As [[previously mentioned ClassesAndTypes]], the type of classes is _type_, which is to say that class objects are instances of _type_: >>> isinstance(A, type) True >>> isinstance(B, type) True Both A and B are clearly subclasses of _object_; A is a direct subclass and B is indirectly a subclass through A. In fact every new-style Python class is a subclass of _object_, since _object_ is the root of the class inheritance tree. However, class type is not the same as class inheritance: >>> issubclass(B, A) True >>> isinstance(B, A) False Although B is a subclass of A, it is not an *instance* of A; it is a direct instance of _type_ (we can see this with '_type(B)_'). Now, given that A and B are instances of _type_, one might expect that they would not be instances of _object_ since they merely inherit from it, as B inherits from A: >>> isinstance(A, object) True Well, how about that. We're wrong (well, I'm wrong, you may already have known the correct answer). Here is why: >>> issubclass(type, object) True A and B are instances of _type_ and, like all other classes and types, _type_ is a subclass of _object_. So A and B are also instances of _object_ (at least in an abstract, Python level view of things), in the same way that an instance of B would also be an instance of A. I believe that this implies that '_isinstance(X, object)_' is always true for anything involved in the new-style Python object system. The corollary is that this is an (almost) surefire test to see if the random object you are dealing with is an old style class or an instance of one: class C: pass >>> issubclass(C, object) False >>> isinstance(C, object) False (This goes away in Python 3, where there is only new-style classes and there is much rejoicing, along with people no longer having to explicitly inherit from _object_ for everything.) PS: as originally noted by [[Peter Donis on a comment here ClassesAndTypes]], _object_ is also an instance of _type_ because _object_ is itself a class. _type_ is an instance of itself in addition to being a subclass of _object_. Try not to think about the recursion too much. (This _isinstance()_ surprise is an easy thing to get wrong, which is why I'm writing it down; I almost made this mistake in another entry I'm working on.) === Sidebar: _isinstance()_ and metaclasses If A (or B) has a metaclass, [[it is an instance of the metaclass UnderstandingTypes]] instead of a direct instance of _type_. In any sane Python program, '_isinstance(A, type)_' will continue to be _True_ because A's metaclass will itself be a subclass of _type_. (I'm not even sure it's possible to create a working metaclass class that doesn't directly or indirectly subclass _type_ ([[cf UsingMetaclass04]]), but I'm not going to bet against it.) This implies that I was dead wrong when I said, back in ClassesAndTypes, that '_type(type(obj))_' would always be '_type_' for any arbitrary Python object, as Daniel Martin noted at the time and I never acknowledged (my bad). In the presence of metaclasses, _type(type(obj))_ can be the metaclass instead of _type_ itself. Since metaclasses can themselves have metaclasses, so there is no guarantee that any fixed number of _type()_ invocations will wind up at _type_.