все Python 3ООПпонятие
Операторные методы
магические методы
Перегрузка операторов. __add__(+), __sub__(-), __mul__(*), __eq__(==), __lt__(<), __le__(<=), __hash__, __neg__.
Синтаксис
def __add__(self, other): ...
Как только вы определяете __eq__, Python обнуляет __hash__ и объекты становятся нехешируемыми (не лягут в set или dict) — верните __hash__ вручную, если он нужен. Если операция не поддерживает второй операнд, возвращайте NotImplemented, а не бросайте исключение: тогда Python попробует зеркальный метод вроде __radd__ у другого объекта, а functools.total_ordering достроит остальные сравнения из __eq__ и одного __lt__.
Примеры
class Vector:
def __init__(self, x, y):
self.x = x; self.y = y
def __add__(self, other):
return Vector(self.x+other.x, self.y+other.y)
def __mul__(self, scalar):
return Vector(self.x*scalar, self.y*scalar)
def __repr__(self):
return f'Vector({self.x},{self.y})'
v1 = Vector(1,2); v2 = Vector(3,4)
print(v1+v2) # → Vector(4,6)
print(v1*3) # → Vector(3,6)
class Fraction:
def __init__(self, n, d):
from math import gcd
g = gcd(abs(n), abs(d))
self.n = n//g; self.d = d//g
def __add__(self, other):
return Fraction(self.n*other.d + other.n*self.d, self.d*other.d)
def __repr__(self):
return f'{self.n}/{self.d}'
print(Fraction(1,3)+Fraction(1,6)) # → 1/2
class MyStr:
def __init__(self, s):
self.s = s
def __add__(self, other):
return MyStr(self.s + other.s)
def __mul__(self, n):
return MyStr(self.s * n)
def __repr__(self):
return repr(self.s)
print(MyStr('hi')*3) # → 'hihihi'
class Point:
def __init__(self, x, y):
self.x = x; self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __lt__(self, other):
return (self.x**2+self.y**2) < (other.x**2+other.y**2)
points = [Point(3,4), Point(1,1), Point(0,5)]
print(sorted(points, key=lambda p: (p.x**2+p.y**2))) # по расстоянию
print(Point(1,1) == Point(1,1)) # → True
class Temperature:
def __init__(self, c):
self.c = c
def __eq__(self, other):
return self.c == other.c
def __lt__(self, other):
return self.c < other.c
def __le__(self, other):
return self.c <= other.c
t1 = Temperature(20); t2 = Temperature(30)
print(t1 < t2, t1 == t2) # → True False
# __neg__, __abs__
class Num:
def __init__(self, v):
self.v = v
def __neg__(self):
return Num(-self.v)
def __abs__(self):
return Num(abs(self.v))
def __repr__(self):
return f'Num({self.v})'
print(-Num(5)) # → Num(-5)
print(abs(Num(-3))) # → Num(3)
# __iadd__ (+=)
class Counter:
def __init__(self, n=0):
self.n = n
def __iadd__(self, other):
self.n += other
return self
def __repr__(self):
return f'Counter({self.n})'
c = Counter(5)
c += 3
print(c) # → Counter(8)
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности