Below are the operators that can be overloaded in classes, along with the method definitions that are required, and an example of the operator in use within an expression.

N.B. The use of other as a variable name is not mandatory, but is considered the norm.

``````            Operator    Method      Expression

Subtraction

sub(self, other) a1 – a2
Multiplication

`mul(self, other) a1 * a2Matrix Multiplication (Python 3.5)@ matmul(self, other)a1 @ a2Division (Python 2 only)/ div(self, other)a1 / a2Division (Python 3)/ truediv(self, other)a1 / a2Floor Division// floordiv(self, other) a1 // a2Modulo/Remainder% mod(self, other) a1 % a2Power** pow(self, other[, modulo]) a1 ** a2Bitwise Left Shift<< lshift(self, other) a1 << a2Bitwise Right Shift`
``````   __rshift__(self, other)             a1  >> a2
Bitwise AND                                             ``````
`& and(self, other) a1 & a2Bitwise XOR^ xor(self, other) a1 ^ a2(Bitwise OR)| or(self, other) a1 | a2Negation (Arithmetic)`

neg(self) -a1
Positive

`pos(self) +a1Bitwise NOT~ invert(self) ~a1Less than< lt(self, other) a1 < a2 Less than or Equal to <= le(self, other) a1 <= a2 Equal to == eq(self, other) a1 == a2 Not Equal to != ne(self, other) a1 != a2 Greater than gt(self, other) a1 > a2Greater than or Equal to= ge(self, other) a1 >= a2Index operator[index] getitem(self, index) a1[index]In operatorin contains(self, other) a2 in a1Calling(*args, …) call(self, *args, *kwargs) a1(args, **kwargs)The optional parameter modulo for pow is only used by the pow built-in function.`

Each of the methods corresponding to a binary operator has a corresponding “right” method which start with r, for example __radd:

```class A:
def init(self, a):
self.a = a
return self.a + other
`return other + self.aA(1) + 2 # Out: 32 + A(1) # prints radd. Out: 3`

as well as a corresponding inplace version, starting with __i:

`class B:def init(self, b):self.b = bdef iadd(self, other):self.b += otherprint("iadd")return selfb = B(2)`

#### Out: 2

`b += 1 # prints iadd`

#### Out: 3

Since there’s nothing special about these methods, many other parts of the language, parts of the standard library, and even third-party modules add magic methods on their own, like methods to cast an object to a type or checking properties of the object. For example, the builtin str() function calls the object’s str method, if it exists. Some of these uses are listed below.

`Function Method ExpressionCasting toint int(self) int(a1)Absolute functionabs(self) abs(a1)Casting tostr str(self) str(a1)Casting to (Python 2 only)unicode(self)unicode unicode(a1)String representationrepr(self) repr(a1)Casting tobool nonzero(self) bool(a1)String formattingformat(self, formatstr) "Hi {:abc}".format(a1)Hashinghash(self) hash(a1)Lengthlen(self) len(a1)Reversedreversed(self) reversed(a1)Floorfloor(self) math.floor(a1)Ceilingceil(self) math.ceil(a1)There are also the special methods enter and exit for context managers, and many more.`

Magic (also called dunder as an abbreviation for double-underscore) methods in Python serve a similar purpose to operator overloading in other languages. They allow a class to define its behavior when it is used as an operand in unary or binary operator expressions. They also serve as implementations called by some built-in functions.

Consider this implementation of two-dimensional vectors.

`import mathclass Vector(object):`

#### instantiation

`def init(self, x, y):`
`self.x = xself.y = yunary negation (-v) def neg(self):return Vector(-self.x, -self.y)addition (v + u)def add(self, other):return Vector(self.x + other.x, self.y + other.y)`

#### subtraction (v – u)

`def sub(self, other):return self + (-other)`

#### equality (v == u)

`def eq(self, other):return self.x == other.x and self.y == other.y`

#### abs(v)

`def abs(self):return math.hypot(self.x, self.y)`

#### str(v)

`def str(self):return '<{0.x}, {0.y}>'.format(self)`

#### repr(v)

`def repr(self):return 'Vector({0.x}, {0.y})'.format(self)`

Now it is possible to naturally use instances of the Vector class in various expressions.

`v = Vector(1, 4)u = Vector(2, 0)u + v # Vector(3, 4)print(u + v) # "<3, 4>" (implicit string conversion)u - v # Vector(1, -4)u == v # Falseu + v == v + u # Trueabs(u + v) # 5.0`

It is possible to emulate container types, which support accessing values by key or index.

Consider this naive implementation of a sparse list, which stores only its non-zero elements to conserve memory.

`class sparselist(object):def init(self, size):self.size = sizeself.data = {}`
##### l[index]
```def getitem(self, index):
if index < 0: index += self.size if index >= self.size:
raise IndexError(index)```
`try:return self.data[index]except KeyError:return 0.0`

#### l[index] = value

`def setitem(self, index, value):self.data[index] = value`

#### del l[index]

`def delitem(self, index):if index in self.data:del self.data[index]`

#### value in l

`def contains(self, value):return value == 0.0 or value in self.data.values()`

#### len(l)

`def len(self):return self.sizefor value in l: …def iter(self):return (self[i] for i in range(self.size)) # use xrange for python2`

Then, we can use a sparselist much like a regular list.

`l = sparselist(10 ** 6) # list with 1 million elements0 in l # True10 in l # Falsel[12345] = 1010 in l # Truel[12345] # 10for v in l:pass # 0, 0, 0, … 10, 0, 0 … 0`

## Callable types

`class adder(object):def init(self, first):self.first = first`

### a(…)

`def call(self, second):return self.first + secondadd2 = adder(2)add2(1) # 3add2(2) # 4`

If your class doesn’t implement a specific overloaded operator for the argument types provided, it should return NotImplemented (note that this is a special constant, not the same as NotImplementedError). This will allow Python to fall back to trying other methods to make the operation work:

When NotImplemented is returned, the interpreter will then try the reflected operation on the other type, or some other fallback, depending on the operator. If all attempted operations return NotImplemented, the interpreter will raise an appropriate exception.

`class NotAddable(object):def init(self, value):self.value = valuedef add(self, other):return NotImplementedclass Addable(NotAddable):def add(self, other):return Addable(self.value + other.value)radd = add`

As this is the reflected method we have to implement add and radd to get the expected behaviour in all cases; fortunately, as they are both doing the same thing in this simple example, we can take a shortcut.

In use:

`x = NotAddable(1)y = Addable(2)x + xTraceback (most recent call last):File "", line 1, inTypeError: unsupported operand type(s) for +: 'NotAddable' and 'NotAddable'y + yz = x + yzz.value3`