32

How do you explain isinstance(Hello,object) returns True whilst issubclass(Hello,object) returns False?

>>> class Hello:
    pass

and

>>> isinstance(Hello,object)
True
>>> issubclass(Hello,object)
False
>>> a = Hello()
>>> isinstance(a,object)
True
bad_coder
  • 11,289
  • 20
  • 44
  • 72
Tarik
  • 79,711
  • 83
  • 236
  • 349

4 Answers4

97

The accepted answer is correct, but seems to miss an important point. The built-in functions isinstance and issubclass ask two different questions.

isinstance(object, classinfo) asks whether an object is an instance of a class (or a tuple of classes).

issubclass(class, classinfo) asks whether one class is a subclass of another class (or other classes).

In either method, classinfo can be a “class, type, or tuple of classes, types, and such tuples.”

Since classes are themselves objects, isinstance applies just fine. We can also ask whether a class is a subclass of another class. But, we shouldn't necessarily expect the same answer from both questions.

class Foo(object):
    pass

class Bar(Foo):
    pass

issubclass(Bar, Foo)
#>True
isinstance(Bar, Foo)
#>False

Bar is a subclass of Foo, not an instance of it. Bar is an instance of type which is a subclass of object, therefore the class Bar is an instance of object.

isinstance(Bar, type)
#>True
issubclass(type, object)
#>True
isinstance(Bar, object)
#>True
cbare
  • 12,060
  • 8
  • 56
  • 63
  • `isinstance(Foo, Foo) == False`. So if `isinstance(ob, Foo)==True` you know you have a proper instantiated object `ob` of type `Foo` (or subclass of `Foo`), so you can operate on it safely and correctly – Tino Nov 29 '16 at 08:04
  • You wording seems to mis-indicate that type is a subclass of object, when what I think you meant is: either Bar is a subclass of object, or that type is a metaclass for object. In either case, I think you should correct it. –  Sep 04 '18 at 08:41
  • 1
    Hi @J. C. Rocamonde, thanks for pointing that out. It is true that _type_ is the metaclass of _object_, as you say and _type(object)_ will confirm. It is *also* true that the class _type_ is a subclass of _object_, unless _issubclass(type, object)_ is lying. Magically, _type(type)_ is _type_ and Python's type system pulls itself up by these somewhat circular bootstraps. :) – cbare Sep 04 '18 at 20:29
27

It's because you are using old-style classes so it doesn't derive from object. Try this instead:

class Hello(object):
    pass

>>> issubclass(Hello,object)
True

Old-style classes are deprecated and you shouldn't use them any more.

In Python 3.x all classes are new-style and writing (object) is no longer required.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • 8
    Worth noting: this applies to Python 2. In Python 3 there's no need for deriving from `object` explicitly. – Cat Plus Plus Nov 12 '11 at 20:30
  • And how to define new-style classes then? Thanks. – Tarik Nov 12 '11 at 20:40
  • 1
    And also why it returns True for `isintance()`? If they are not derived from object... – Tarik Nov 12 '11 at 20:42
  • 6
    Old style classes are instances (not subclasses!) of `types.ClassType` type. As all types, it's a subclass of `object`, that's why any old style class is an instance of `object` type. – yak Nov 12 '11 at 22:03
18

My answer pertains to Python 3.

To expand upon cbare's answer, the code below was helpful for me.

>>> class X:
...     pass
...     
>>> class Y(X):
...     pass
...     
>>> x = X()
>>> y = Y()
>>> isinstance(x, X)  # is object x an instance of class X (or any subclass)?
True
>>> isinstance(x, Y)  # is object x an instance of class Y (or any subclass)?
False
>>> isinstance(y, X)  # is object y an instance of class X (or any subclass)?
True
>>> isinstance(y, Y)  # is object y an instance of class Y (or any subclass)?
True

>>> issubclass(X, X)  # is class X a subclass of X (including class X)?
True
>>> issubclass(X, Y)  # is class X a subclass of Y (including class Y)?
False
>>> issubclass(Y, X)  # is class Y a subclass of X (including class X)?
True
>>> issubclass(Y, Y)  # is class Y a subclass of Y (including class Y)?
True

>>> issubclass(type(x), X)  # is class of object x a subclass of X (including class X)?
True
>>> issubclass(type(x), Y)  # is class of object x a subclass of Y (including class Y)?
False
>>> issubclass(type(y), X)  # is class of object y a subclass of X (including class X)?
True
>>> issubclass(type(y), Y)  # is class of object y a subclass of Y (including class Y)?
True

>>> issubclass(x.__class__, X)  # is class of object x a subclass of X (including class X)?
True
>>> issubclass(x.__class__, Y)  # is class of object x a subclass of Y (including class Y)?
False
>>> issubclass(y.__class__, X)  # is class of object y a subclass of X (including class X)?
True
>>> issubclass(y.__class__, Y)  # is class of object y a subclass of Y (including class Y)?
True

We can see that isinstance(object, class) respects inheritance / subclasses correctly.

kevinarpe
  • 20,319
  • 26
  • 127
  • 154
  • 2
    This is useful, but could you redo your answer to use different names? E.g. `Person` for the base class with an instance named `john` and `Scientist` for the subclass, with an instance named `einstein`. – Abhishek Divekar Mar 16 '20 at 16:28
0

So basically isinstance(new_object, some_class) returns True if the object is an instantiated class of some_class. In other words, new_object is an some_class() object. issubclass checks if the object has a subclass of some_class.

Better explained with a simple example that makes perfect sense:

class some_class():
  pass

class new_object_class(some_class):
  pass

instance_object = new_object_class()

isinstance(instance_object, new_object_class) == True
issubclass(instance_object, some_class) == True

isinstance(new_object_class,some_class) == True
issubclass(new_object_class,some_class) == True

No need for false tests to explain this.

bauderr
  • 47
  • 10