8. Operator Overload

8.1. Why to use operator overload?

  • Readable syntax

  • Simpler operations

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


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

suma = vector1 + vector2
# TypeError: unsupported operand type(s) for +: 'Vector' and 'Vector'
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)

8.2. Operator Overload

8.2.1. Numerical Operators

Table 31. Numerical Operator Overload

Operator

Method

a + b

__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__()

8.2.2. Comparison Operators

Table 32. Comparison Operators Overload

Operator

Method

a == b

__eq__()

a != b

__ne__()

a < b

__lt__()

a <= b

__le__()

a > b

__gt__()

a >= b

__ge__()

8.2.3. Boolean Operators

Table 33. Boolean Operators Overload

Operator

Method

-a

__neg__()

+a

__pos__

a & b

__and__()

a | b

__or__()

a ^ b

__xor__()

a << b

__lshift__()

a >> b

__rshift__()

8.2.4. Builtin Functions

Table 34. Builtin Functions Overload

Function

Method

abs(a)

__abs__()

bool(a)

__bool__()

divmod(a, b)

__divmod__()

pow(a)

__pow__()

round(a, prec)

__round__()

dir(a)

__dir__()

len(a)

__len__()

delattr(cls, 'a')

__delattr__()

complex(a)

__complex__()

int(a)

__int__()

float(a)

__float__()

oct(a)

__oct__()

hex(a)

__hex__()

reversed()

__reversed__()

from math import sqrt


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

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


vector = Vector(x=3, y=4)
abs(vector)
# 5.0

8.2.5. Builtin keywords

Table 35. Builtin Keywords Overload

Keyword

Method

del a

__delattr__()

8.2.6. Accessors Overload

Table 36. Operator Overload

Operator

Description

a[b]

__getitem__()

a[b] = 10

__setitem__()

a in b

__contains__()

a[b] (when b is not in a)

__missing__()

8.3. Example

8.3.1. Modulo operator for int and str

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.

8.3.2. Contains in numpy

import numpy as np

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

a[1][2]  # 6
a[1,2]   # 6
Listing 308. Intuitive implementation of numpy array[row,col] accessor
class array(list):
    def __getitem__(key):
        row = key[0]
        col = key[1]
        return super().__getitem__(row).__getitem__(col)

# a[1,2]
a.__getitem__(key=(1,2))

8.4. Assignment

8.4.1. Address Book

  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(first_name='Jan', last_name='Twardowski', addresses=(
    Address(center='Johnson Space Center', location='Houston, TX'),
    Address(center='Kennedy Space Center', location='Merritt Island, FL'),
))

contact += Address(center='Jet Propulsion Laboratory', location='Pasadena, CA'),
contact += Address(center='Armstrong Flight Research Center', location='Edwards AFB, CA'),

print(contact)
# {'first_name': 'Jan', 'last_name':'Twardowski', 'addresses': [
#       {'center': 'Johnson Space Center', 'location': 'Houston, TX'},
#       {'center': 'Kennedy Space Center', 'location': 'Merritt Island, FL'},
#       {'center': 'Jet Propulsion Laboratory', 'location': 'Pasadena, CA'},
#       {'center': 'Armstrong Flight Research Center', 'location': 'Edwards AFB, CA'}
# ]}

if Address(center='Armstrong Flight Research Center', location='Edwards AFB, CA') in contact:
    print(True)
else:
    print(False)
# True