About special method names
Python has multiple layers of implementation. We're interested in just two of them.
On the surface, we have Python's source text. This source text is a mixture of a traditional object-oriented notation and procedural function call notation. The postfix object-oriented notation includes object.method()
or object.attribute
constructs. The prefix notation involves function(object)
constructs that are more typical of procedural programming languages. We also have an infix notation such as object+other
. Plus, of course, some statements such as for
and with
invoke object methods.
The presence of function(object)
prefix constructs leads some programmers to question the "purity" of Python's object orientation. It's not clear that a fastidiously strict adherence to the object.method()
notation is necessary or even helpful. Python uses a mixture of prefix and suffix notations. The prefix notations are stand-ins for special method suffix notations. The presence of the prefix, infix, and postfix notations is based on choices of expressiveness and esthetics. One goal of well-written Python is that it should read more or less like English. Underneath the hood, the syntax variations are implemented consistently by Python's special methods.
Everything in Python is an object. This is unlike Java or C++ where there are "primitive" types that avoid the object paradigm. Every Python object offers an array of special methods that provide implementation details for the surface features of the language. We might, for example, write str(x)
in an application program. This prefix surface notation is implemented as x.__str__()
under the hood.
A construct such as a+b
may be implemented as a.__add__(b)
or b.__radd__(a)
depending on the type of compatibility rules that were built into the class definitions for objects a
and b
.
The mapping between surface syntax and the implementation of special methods is emphatically not a trivial rewrite from function(x)
to x.__function__()
. There are numerous language features that have interesting special methods to support that feature. Some special methods have default implementations inherited from the base class, object
, while other special methods have no default implementation and will raise an exception.
Throughout Part 1, Pythonic Classes via Special Methods, we'll introduce the special methods and show how we can implement these special methods to provide seamless integration between Python and our class definitions.