Data Model

Operator Overloading

Operator methods let objects define arithmetic and comparison syntax.

__add__ defines how the + operator combines two objects. Checking the operand type and returning NotImplemented for foreign types lets Python try the other operand's reflected method instead of crashing inside yours.

Source

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

    def __add__(self, other):
        if not isinstance(other, Vector):
            return NotImplemented
        return Vector(self.x + other.x, self.y + other.y)

    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

print(Vector(2, 3) + Vector(4, 5))

Output

Vector(6, 8)
Defining __add__ on a class lets + dispatch into the class's own behavior.

__eq__ defines value equality for ==. Without it, user-defined objects compare by identity. Returning NotImplemented for foreign types matters most here: equality against an unrelated value should answer False, never raise — Python falls back to identity when both sides decline.

Source

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

    def __eq__(self, other):
        if not isinstance(other, Vector):
            return NotImplemented
        return (self.x, self.y) == (other.x, other.y)

print(Vector(1, 1) == Vector(1, 1))
print(Vector(1, 1) == 5)

Output

True
False

A useful __repr__ makes operator results inspectable while debugging.

Source

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

    def __add__(self, other):
        if not isinstance(other, Vector):
            return NotImplemented
        return Vector(self.x + other.x, self.y + other.y)

    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

print(repr(Vector(2, 3) + Vector(4, 5)))

Output

Vector(6, 8)

Notes

See also

Run the complete example

Example code

Expected output

Vector(6, 8)
True
False

Execution time appears here after you run the example.