Language
Classes
Classes are state containers and namespaces, not the primary abstraction. This is a design choice. Two patterns cover most uses.
- State machines. A few methods mutate the receiver.
- Namespaces. A class bundles related functions and constants.
The class model supports these features.
- Single and multiple inheritance (C3 MRO) with
super(). @propertyand@x.setter.@staticmethodand@classmethod.- A curated dunder protocol for operators, indexing, iteration, hashing, context managers and attribute fallback. See Operator overloading and protocols.
Any other dunder a class body binds, and a class keyword such as metaclass=, fails at compile time. Limits and errors lists each one.
State-machine pattern
3
Namespace pattern
A class with no __init__ and no per-instance state is a namespace. Its functions are called on the class itself.
0 3.14159 25 27
Inheritance and super()
A class takes one base or several, as in class Sub(Base): and class C(A, B):.
- Methods missing on the subclass resolve along the C3 linearization, the MRO.
- An inconsistent hierarchy raises
TypeErrorat class creation. isinstance(x, Base)walks the ancestor chain. ASubinstance is an instance of every ancestor.
super() with no arguments delegates to the next class up the chain, bound to the current self. It is most common in __init__ to extend a base constructor.
Rex (lab) True
B inconsistent hierarchy
Attribute access on classes vs instances
| Access form | Resolves to |
|---|---|
MyClass.attr | class member, returned as-is (no binding) |
MyClass.method() | method called directly, no self |
instance.attr | instance __dict__ first, then class |
instance.method() | bound method, self prepended |
setattr and delattr work on instances and on class objects. On a class object they change the members of the class.
Class decorators
A class decorator is called with the class object, and its return value binds to the name. It can add or replace class attributes (cls.kind = ...) or return a replacement.
tagged 7
Properties
@property turns a method into a read-only attribute. @x.setter makes it writable. Properties live on the class, and subclasses inherit and can override either side.
20 68.0 212.0
Static methods
@staticmethod makes a method that receives no implicit self. It is a plain function in the class namespace.
- It is callable as
Class.method(...)orinstance.method(...)with the same arguments. - Subclasses inherit it and can override it.
- It suits helpers that belong to a class but need no receiver.
5 20.0
Class methods
@classmethod binds the class, not the instance, as the first argument. Through a subclass, cls is the subclass. Alternate constructors then return the right type down the hierarchy.
1 2 Color Bright
The three decorators also work as plain calls without decorator syntax. The forms are property(fget, fset), staticmethod(func) and classmethod(func).
Operator overloading and protocols
Dunders such as __add__, __eq__ and __getitem__ plug a class into language protocols. Define them in the class body. The engine calls them when the matching operator, builtin or syntax form runs.
7 True
Dunders are looked up on the class chain, and subclasses inherit them and may override them. The instance dict is skipped. Assigning obj.__add__ = ... has no effect.
Arithmetic
| Operator | Forward | Reflected |
|---|---|---|
a + b | __add__ | __radd__ |
a - b | __sub__ | __rsub__ |
a * b | __mul__ | __rmul__ |
a / b | __truediv__ | __rtruediv__ |
a // b | __floordiv__ | __rfloordiv__ |
a % b | __mod__ | __rmod__ |
a ** b | __pow__ | __rpow__ |
a @ b | __matmul__ | __rmatmul__ |
-a | __neg__ | - |
+a | __pos__ | - |
The engine picks between the forward and the reflected dunder by these rules.
- A forward dunder that returns
NotImplementedmakes the engine try the reflected one on the other operand. - If both return
NotImplemented, or neither is defined, the operation raisesTypeError. - When
type(b)is a strict subclass oftype(a),b.__radd__runs beforea.__add__. A subclass can then override an inherited reflected op without touching the base. - An augmented assignment such as
a += bfirst calls the in-place dunder (__iadd__,__imatmul__and the rest). It falls back to the pair above when that dunder is missing or returnsNotImplemented.
15 10
Bitwise and shifts
The bitwise and shift operators follow the same forward and reflected protocol.
| Operator | Forward | Reflected |
|---|---|---|
a | b | __or__ | __ror__ |
a & b | __and__ | __rand__ |
a ^ b | __xor__ | __rxor__ |
a << b | __lshift__ | __rlshift__ |
a >> b | __rshift__ | __rrshift__ |
~a | __invert__ | - |
Comparison
| Operator | Forward | Reflected |
|---|---|---|
a == b | __eq__ | __eq__ |
a != b | __ne__ | __ne__ |
a < b | __lt__ | __gt__ |
a <= b | __le__ | __ge__ |
a > b | __gt__ | __lt__ |
a >= b | __ge__ | __le__ |
When __ne__ is absent, != falls back to not __eq__, coerced to bool. Every other comparison returns the raw result of its dunder. A __lt__ that returns 'A.lt' yields the string, not True.
True False
Truth and length
bool(x) and any boolean context consult these in order.
__bool__if defined. It must returnbool, elseTypeError.__len__if defined.Falsewhen the length is 0, elseTrue.- Default
True.
len(x) calls __len__ directly. It must return a non-negative int.
False False True 5
Indexing and containment
| Form | Dunder | Arguments |
|---|---|---|
obj[i] | __getitem__ | (self, i) |
obj[i] = v | __setitem__ | (self, i, value) |
del obj[i] | __delitem__ | (self, i) |
v in obj | __contains__ | (self, value) |
- Slices pass as a
sliceobject.obj[1:3]calls__getitem__(self, slice(1, 3, None)). - Indexes on builtin sequences coerce through
__index__, slice bounds included. Dict keys never coerce. - Without
__contains__,v in objiteratesobjand compares with__eq__.
1 missing True False
Iteration
| Method | Role |
|---|---|
__iter__ | Returns an iterator (often self). |
__next__ | Returns the next item, or raises StopIteration to end the loop. |
[1, 2, 3] True
for loops, list(x) and tuple(x) all honor the protocol.
Callable
__call__ makes instances callable. Positional and keyword arguments pass through like any method call.
14 21 True
Hashing
An instance hashes by identity, so it can be a dict key or a set item. A class that defines __eq__ is unhashable, and {x: 1} raises TypeError, since two equal instances could hash apart.
found False
Representation
| Function / form | Dunder | Fallback |
|---|---|---|
repr(x) | __repr__ | <ClassName instance> |
str(x), print(x) | __str__ | __repr__, then default |
f"{x}" (no spec) | __str__ | same as str(x) |
f"{x:spec}" | __format__ | TypeError for a non-empty spec |
f"{x!r}" | __repr__ | - |
__format__(spec) receives the spec string and must return str.
P(3) P(3) P(3) [P(3)]
Numeric conversion
| Function / form | Dunder | Fallback |
|---|---|---|
int(x) | __int__ | - |
float(x) | __float__ | __index__ |
abs(x) | __abs__ | - |
%d, %x, %X, %o | __int__ | - |
12 12.5 5 12 dollars
Attribute access fallback
__getattr__(self, name) runs only when normal lookup misses. Normal lookup checks the instance dict, then the class chain. The dunder receives the name as a string and returns the value, or raises AttributeError to report a real miss.
1 computed:anything computed:foo
Context managers
__enter__ and __exit__ make an instance usable in with. Control flow covers the order of calls, the arguments of __exit__ and suppression.
Reuse behavior through free functions and composition by default. Reach for inheritance and operator overloading when the abstraction calls for them.