В Python 3 1 используйте __truediv__
для /
и __floordiv__
для (//
).
Это также работает в Python 2 с from __future__ import division
(что приводит к тому, что деление ведет себя как в Python 3).
Вот два дополнительных совета:
Во-первых, вместо проверки точных типов float
и int
,вы можете использовать классы в модуле numbers
для проверки числовых типов.
Во-вторых, вы должны вернуть NotImplemented
из переопределенного двоичного оператора, если он не знает, что делатьделать с заданным значением. Затем Python проверит, реализует ли другой операнд перевернутую версию оператора (т. Е. __r[name]__
), и попытается это сделать. Если это также возвращает NotImplemented
, Python повысит TypeError
. Это позволяет создавать классы, которые можно использовать с обеих сторон операторов.
import numbers
class Vector1D:
def __init__(self, x):
self.x = x
def __repr__(self, x):
return "Vector1D({})".format(self.x)
def __mul__(self, other):
if isinstance(other, numbers.Number):
return self.__class__(self.x * other)
return NotImplemented
def __rmul__(self, other):
# x * vec1d == vec1d * x
return self.__mul__(other)
def __rtruediv__(self, other):
# You can't divide things by a Vector1D
return NotImplemented
vec2 = Vector1D(2)
vec2 * 3
# Runs vec2.__mul__(2), gets Vector1D(6)
3 * vec2
# First tries int.__mul__(3, vec2), gets NotImplemented
# Then tries Vector1D.__rmul__(vec2, 3), gets Vector1D(6)
3 / vec2
# First tries int.__truediv__(3, vec2), gets NotImplemented
# Then tries Vector1D.__rtruediv__(vec2, 3), gets NotImplemented
# Python raises TypeError