With the class
statement, we can create a user-defined data type that we also call a class.
Then, to create new instances of the data type, we simply call the class, just as we do with the built-in constructors.
Conceptually, a class is the blueprint defining the behavior each instance exhibits.
In the example used throughout the chapter, the Vector
and Matrix
classes implement the linear algebra rules all Vector
and Matrix
instances follow in general. On the contrary, the instances encapsulate the state of concrete vectors and matrices.
The class
statement acts as a namespace that consists of simple variable assignments and function definitions:
self
; it embodies an instance's state: That means that instance methods set and get instance attributes on and from self
.cls
. A common use case is to design alternative constructors.The Python Data Model concerns what special methods (i.e., the ones with the dunder names) exists and how they work together.
The instantiation process is controlled by the .__init__()
method.
The __repr__()
and __str__()
methods implement the text representation of an instance, which can be regarded as a Unicode encoded representation of all the state encapsulated in an instance.
Sequence emulation means that a user-defined data type exhibits the same four properties as the built-in sequences, which are regarded as finite and iterable containers with a predictable order. The .__len__()
, .__iter__()
, __reversed__()
, __getitem__()
, and some others are used to implement the corresponding behaviors.
Similarly, number emulation means that an instance of a user-defined data type behaves like a built-in number. For example, by implementing the .__abs__()
method, an instance may be passed to the built-in abs() function.
If different data types, built-in or user-defined, share a well-defined set of behaviors, a single function may be written to work with objects of all the data types. We describe such functions as polymorphic.
Classes may specify how operators are overloaded. Examples for that are the .__add__()
, .__sub__()
, or .__eq__()
methods.
Packages are folders containing modules (i.e., *.py files) and a "__init__.py" file. We use them to design coherent libraries with reusable code.