Python object model

Everything is an object

In many languages, and also Python, everything is an instance of the class object. None is an object, a number is an object, a function is an object etc. In other words, we have a superclass called object and any class (implicitely) inherits from that superclass object.

from graphviz import Digraph
dot = Digraph(graph_attr=dict(rankdir="BT"), edge_attr={'arrowhead':'empty'})
dot.edges([(X,'object') for X in ["NoneType", "numbers.Number", "types.FunctionType"]])

dot

svg

  • In Java, also every class is a subclass of Java.lang.Object. However, a class, e.g. Animal itself is not an object but Animal.class is and inherits from java.lang.Class.
  • In Python, the class Animal itself is an object too.
  • In C++, there is no superclass.
dir(object)
['__class__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__']
type(1)
int
type(int)
type

True

Number class hierarchy in Python

Here is the class hierarchy for the numbers in Python. See https://peps.python.org/pep-3141/ where you may read the rejected alternatives.

from graphviz import Digraph
dot = Digraph(graph_attr=dict(rankdir="BT"), edge_attr={'arrowhead':'empty'})
dot.edges([('Complex', 'Number'), ('complex', 'Complex'), ('Real', 'Complex'), ('float', 'Real'), ('Rational', 'Real'), ('Integral', 'Rational'), ('int', 'Integral'), ('bool', 'int')])
dot

svg

from numbers import Complex 
dir(Complex)
['__abs__',
 '__abstractmethods__',
 '__add__',
 '__bool__',
 '__class__',
 '__complex__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__mul__',
 '__ne__',
 '__neg__',
 '__new__',
 '__pos__',
 '__pow__',
 '__radd__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rmul__',
 '__rpow__',
 '__rsub__',
 '__rtruediv__',
 '__setattr__',
 '__sizeof__',
 '__slots__',
 '__str__',
 '__sub__',
 '__subclasshook__',
 '__truediv__',
 '_abc_impl',
 'conjugate',
 'imag',
 'real']
import numbers
isinstance(5, numbers.Number)
True

Class hierarchy for Collections in Python

Here is the class hierarchy for collections in Python.

from graphviz import Digraph
dot = Digraph(graph_attr=dict(rankdir="BT"), edge_attr={'arrowhead':'empty'})
dot.edges([("Collection", "Container"),
           ("Collection", "Iterable"),
           ("Collection", "Sized"),
           ("Sequence", "Collection"),
           ("Set", "Collection"),
           ("Mapping", "Collection"),
           ("MutableSequence", "Sequence"),
           ("MutableSet", "Set"),
           ("MutableMapping", "Mapping"),
           ("tuple", "Sequence"),
           ("str", "Sequence"),
           ("bytes", "Sequence"),
           ("list", "MutableSequence"),
           ("bytearray", "MutableSequence"),
           ("frozenset", "Set"),
           ("set", "MutableSet"),
           ("dict", "MutableMapping")])

dot

svg

In Java, https://docs.oracle.com/javase/8/docs/api/java/lang/package-tree.html

from collections import Sized
dir(Sized)
/tmp/ipykernel_646363/3389889515.py:1: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working
  from collections import Sized





['__abstractmethods__',
 '__class__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__len__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__slots__',
 '__str__',
 '__subclasshook__',
 '_abc_impl']
class Farm:
    def __len__(self):
        return 4
    
f = Farm()
len(f)
4
from collections import Sized

class Farm(Sized):
    def __len__(self):
        return 4
    
f: Sized = Farm()
len(f)
4