The Python Object Model

Core structure in detail

A semi-formal description of the Python object model is presented. Currently, only the core structure is described, concerning inheritance, instance relation and attribute resolution order.

In the present scope, this document can be considered as just an appendix to [].

Preface

Author
Ondřej Pavlata
Jablonec nad Nisou
Czech Republic
Document date
Initial releaseAugust 24, 2012
Last major release August 24, 2012
Last updateJanuary 22, 2013
(see Document history)
Warning
  1. This document has been created without any prepublication review except those made by the author himself.
Python version
This document refers to Python 3.x, more specifically, to CPython 3.2.3.

Table of contents

S1: Inheritance and the class map

An S1 structure is a structure (O, , .class, r, c) where Additional notation / terminology is applied: The structure is subject to the following axioms:
(S1~1) The .class map is monotone with respect to inheritance, i.e. for every classes x, y,
  • x y   implies   x.class y.class.
(S1~2) The inheritance is a partial order between objects. In addition,
  • r is the highest class (the top of (C, )),
  • terminals are minimal – they have no strict descendants.
(S1~3) The set {r, c} forms the least substructure. More specifically,
  • r is different from c and is the only strict inheritance ancestor of c,
  • r.class = c.
Equivalently, {r, c} is a 2-element set that is an up-set both in inheritance and the instance tree.
(S1~4) For every terminal object x,
  • x.class c,
i.e. the class of a terminal object is not a metaclass.
(S1~5) The .class map forms a tree on objects called the instance tree. In addition,
  • c is the root,
  • terminals are (among the) leaves, i.e. the class of an object is a class.

Proposition:

The following table shows how the structure is reflected using the Python built-in functions.
NotationTerminologyPython expression
r inheritance root object
c metaclass root type
x is a class isinstance(x,type)
x is a metaclass issubclass(x,type)
x.class the class of x x.__class__
x y x is a descendant of y issubclass(x,y)
x.class y x is an instance of y isinstance(x,y)

Note: As of version 3.2, Python allows structures that do NOT satisfy condition (S1~2). This is shown by the following code.

class M(type):
  def mro(x): return []
class X(metaclass=M): pass
print (issubclass(X,X))      # False
print (issubclass(X,object)) # False

S2: Attribute (/ method) resolution order – MRO

An S2 structure is an S1 structure equipped with (._mro, ._bas) where

For classes x, y, we write

For a class x, elements of x._bas are (direct) superclasses of x.

The structure is subject to the following conditions:

(S2~1) The inheritance is obtained from ._mro by
  • x y   iff   y appears in x._mro
for every classes x, y.
(S2~2) The inheritance is also obtained from ._bas as the reflexive transitive closure of .
(S2~3) For every class x,
  • (a) the list x._mro is non-repetitive, starts with x and ends with r,
  • (b) the list x._bas is non-repetitive and does not contain x.

 

References
Mark Lutz, Learning Python, O'Reilly 2009
Ondřej Pavlata, Object Membership: The core structure of object-oriented programming, 2012–2014, http://www.atalon.cz/om/object-membership/oop/
Chris Siebenmann, Python's attribute lookup order, 2011, http://utcc.utoronto.ca/~cks/space/blog/python/AttributeLookupOrder

 

Document history
August242012 The initial release.
January222013 Conditions (S1~1) and (S1~5) exchanged in order to be in a correspondence with axioms of S1p.pr structures.
License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License.