16

How is it possible to have an instance of a class which is an object, without the class being a subclass of object? here is an example:

>>> class OldStyle(): pass
>>> issubclass(OldStyle, object)
False
>>> old_style = OldStyle()
>>> isinstance(old_style, object)
True
Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260

3 Answers3

18

In Python 2, type and class are not the same thing, specifically, for old-style classes, type(obj) is not the same object as obj.__class__. So it is possible because instances of old-style classes are actually of a different type (instance) than their class:

>>> class A(): pass
>>> class B(A): pass
>>> b = B()

>>> assert b.__class__ is B
>>> issubclass(b.__class__, A) # same as issubclass(B, A)
True
>>> issubclass(type(b), A)
False

>>> type(b)
<type 'instance'>
>>> b.__class__
<class __main__.B at 0x10043aa10>

This is resolved in new-style classes:

>>> class NA(object): pass
>>> class NB(NA): pass
>>> nb = NB()
>>> issubclass(type(nb), NA)
True
>>> type(nb)
<class '__main__.NB'>
>>> nb.__class__
<class '__main__.NB'>

Old-style class is not a type, new-style class is:

>>> isinstance(A, type)
False
>>> isinstance(NA, type)
True

Old style classes are declared deprecated. In Python 3, there are only new-style classes; class A() is equivalent to class A(object) and your code will yield True in both checks.

Take a look at this question for some more discussion: What is the difference between old style and new style classes in Python?

Community
  • 1
  • 1
hamstergene
  • 24,039
  • 5
  • 57
  • 72
  • +1: This is a very clear description, and a very good point. Thanks! – Eric O. Lebigot Mar 14 '12 at 12:26
  • For anyone wondering, `isinstance` is [special-cased](https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects/abstract.c#L2898) for old-style instances and classes (i.e. `PyClass_Check(cls) && PyInstance_Check(inst)` in C). Since there's no type-based relationship, it gets the `__class__` of the instance for an `issubclass` check, which is also [special-cased](https://github.com/python/cpython/blob/e6a0b5982973e64b9fa28e5e3e54eb8c47882780/Objects/classobject.c#L486) for old-style classes. – Eryk Sun Jun 15 '17 at 13:04
6

Everything is an object:

isinstance(123, object) # True
isinstance("green cheese", object) # True
isinstance(someOldClassObject, object) # True
isinstance(someNewClassObject, object) # True
isinstance(object, object) # True
isinstance(None, object) # True

Note that this question has essentially nothing to do with old- vs. new-style classes. isinstance(old_style, object) being True is simply a corollary of the fact that every value in python is an instance of object.

georg
  • 211,518
  • 52
  • 313
  • 390
  • Do you have a reference on this? – Eric O. Lebigot Mar 14 '12 at 12:22
  • 1
    @EOL: [this one](http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html) is quite helpful – georg Mar 14 '12 at 12:32
  • 1
    Thanks. I had a look at the reference, but I can't find anywhere any indication of the idea that everything in Python is of *type* `object` (the fact that "everything is an object" in Python does not mean the same thing). – Eric O. Lebigot Mar 14 '12 at 13:48
1

When you do the expression

   old_style = OldStyle()

It means you are instantiating the object, which old_style is an instance of the class OldStyle.

Also, both evaluates to True in Python 3.2.

hash__x
  • 83
  • 2
  • 9