На мой взгляд, вы должны сделать
return NotImplemented
вместо определения вашего собственного исключения. Смотрите пример ниже для случая, когда это было бы предпочтительнее:
class InvalidOperationException(Exception):
pass
class Vector2D(list):
def __init__(self, a, b):
super().__init__([a, b])
def __add__(self, other):
return Vector2D(self[0] + other[0],
self[1] + other[1])
def __mul__(self, other):
if hasattr(other, '__len__') and len(other) == 2:
return self[0]*other[0] + self[1]*other[1]
return Vector2D(self[0]*other, self[1]*other)
def __rmul__(self, other):
if hasattr(other, '__len__') and len(other) == 2:
return Vector2D(other[0]*self, other[1]*self)
return Vector2D(other*self[0], other*self[1])
class Matrix2D(list):
def __init__(self, v1, v2):
super().__init__([Vector2D(v1[0], v1[1]),
Vector2D(v2[0], v2[1])])
def __add__(self, other):
return Matrix2D(self[0] + other[0],
self[1] + other[1])
def __mul__(self, other):
# Change to:
# return InvalidOperationException
# or:
# raise InvalidOperationException
return NotImplemented
if __name__ == '__main__':
m = Matrix2D((1, -1),
(0, 2))
v = Vector2D(1, 2)
assert v*v == 5 # [1 2] [1] = 5
# [2]
assert v*m == Vector2D(1, 3) # [1 2] [1 -1] = [1 3]
# [0 2]
try:
result = m*m
print('Operation should have raised a TypeError exception, '
'but returned %s as a value instead' % str(result))
except TypeError:
pass
assert m*v == Vector2D(-1, 4) # [1 -1] [1] = [-1]
# [0 2] [2] [ 4]
Он должен работать без ошибок. При выполнении m*v
он пытается вызвать __mul__
из Matrix2D
, но не удается. Если и только если он возвращает NotImplemented
, он пытается вызвать __rmul__
из объекта на правой стороне.