3. Operator Overload

3.1. Why to use operator overload?

  • Readable syntax

  • Simpler operations

3.1.1. Example usage of operator Overload

class Vector:
    def __init__(self, x=0.0, y=0.0):
        self.x = x
        self.y = y

    def __str__(self):
        return f'Vector(x={self.x}, y={self.y})'

    def __add__(self, other):
        return Vector(
            self.x + other.x,
            self.y + other.y
        )

vector1 = Vector(x=1, y=2)
vector2 = Vector(x=3, y=4)
vector3 = Vector(x=5, y=6)

suma = vector1 + vector2
print(suma)
# Vector(x=4, y=6)

suma = vector1 + vector2 + vector3
print(suma)
# Vector(x=9, y=12)

suma = vector1 - vector2
# TypeError: unsupported operand type(s) for +=: 'NoneType' and 'Address'
import math

class Vector:
    def __init__(self, x=0.0, y=0.0):
        self.x = x
        self.y = y

    def __abs__(self):
        return math.sqrt(self.x**2 + self.y**2)

vector1 = Vector(x=1, y=2)
abs(vector1)

3.2. Numerical Operator Overload

Tab. 3.5. Operator Overload

Operator

Description

__add__()

a + b

__iadd__()

a += b

__sub__()

a - b

__isub__()

a -= b

__mul__()

a * b

__imul__()

a *= b

__div__()

a / b

__idiv__()

a /= b

__mod__()

a % b

__divmod__()

divmod(a, b)

__abs__()

abs(a)

__pow__()

pow(a)

__round__()

round(a), or round(a, x), where x is ndigits presision

3.2.1. Example

7 % 2               # 1
'My number' % 2     # TypeError: not all arguments converted during string formatting
'My number %s' % 2  # My number 2
'My number %d' % 2  # My number 2
'My number %f' % 2  # My number 2.0

Note

%s, %d, %f is currently deprecated in favor of f'...' string formatting. The topic will be continued in Print Formatting chapter.

3.3. Logical Operator Overload

Tab. 3.6. Operator Overload

Operator

Description

__eq__()

a == b

__ne__()

a != b

__lt__()

a < b

__le__()

a <= b

__gt__()

a > b

__ge__()

a >= b

__bool__()

bool(a)

__neg__()

-a

__pos__

+a

3.4. Boolean Operator Overload

Tab. 3.7. Operator Overload

Operator

Description

__and__()

a & b

__or__()

a | b

__xor__()

a ^ b

__lshift__()

a << b

__rshift__()

a >> b

3.5. Builtins Function Overload

Tab. 3.8. Operator Overload

Operator

Description

__dir__()

dir(a)

__len__()

len(a)

__delattr__()

delattr(cls, 'a') or del a

__complex__()

complex(a)

__int__()

int(a)

__float__()

float(a)

__oct__()

oct(a)

__hex__()

hex(a)

__reversed__()

reversed()

3.6. Accessors Overload

Tab. 3.9. Operator Overload

Operator

Description

__getitem__()

a[b]

__setitem__()

a[b] = 10

__contains__()

a in b

__missing__()

a[b] when b is not in a

3.6.1. Example

import numpy as np

a = np.array([[1, 2, 3],
              [4, 5, 6]])

a[1][2]  # 6
a[1,2]   # 6

3.7. Assignment

3.7.1. Address Book

  • Filename: oop_addressbook_operators.py

  • Lines of code to write: 10 lines

  • Estimated time of completion: 15 min

  1. Dopisz odpowiednie metody do Contact i Address aby poniższy kod zadziałał poprawnie

class Contact:
    def __str__(self):
        return f'{self.__dict__}'


class Address:
    def __repr__(self):
        return f'{self.__dict__}'


contact = Contact(name='José Jiménez', addresses=[Address(location='JPL')])
contact += Address(location='Houston')
contact += Address(location='KSC')

print(contact)
# {'name': 'José Jiménez', 'addresses': [
#       {'location': 'JPL'},
#       {'location': 'Houston'},
#       {'location': 'KSC'}
# ]}

if Address(location='Houston') in contact:
    print(True)
else:
    print(False)
# True