我有继承自
list
的自定义类。 CustomList
实例支持它们之间的减法以及与常规 lists
的减法。减去 CustomLists/lists
的相应元素。如果 CustomLists/lists
之一较短,则缺失的元素将被视为零。
from typing import Iterable, List
class CustomList(list):
def __init__(self, *args: Iterable[int | float]):
if args == ():
super().__init__(*args)
elif all(isinstance(a, (int, float)) for a in args[0]):
super().__init__(*args)
else:
raise TypeError("CustomList instance can contain int and float datatypes only")
def __sub__(self, other: List[int | float] | "CustomList") -> "CustomList":
if isinstance(other, (self.__class__, list)):
result = CustomList()
for i in range(max(len(self), len(other))):
if i < len(self) and i < len(other):
result.append(self[i] - other[i])
elif i < len(self):
result.append(self[i])
else:
result.append(other[i])
return result
def __rsub__(self, other):
return self.__sub__(other)
__sub__
按预期工作,但是当第一个操作数是列表时(并且调用 __rsub__
) - 减法则相反。它不是 operand1 - operand2
,而是 operand2 - operand1
。[1, 2, 3] - CustomList([2, 4, 6])
应该是 CustomList([-1, -2, -3])
但我得到了 CustomList([1, 2, 3])
。
为什么会出现这种情况?
__rsub__
时,会调用
list - CustomList
,比方说 L - myList
。当您按照您的方式定义 __rsub__
时,您将返回 myList - L
的结果。但减法不可交换 (a - b != b - a
)。
我推荐的解决方案是重载否定运算符 (
__neg__
) 来定义 - myList
是什么。然后修改 __rsub__
返回 - self.__sub__(other)
。
这是完整的解决方案:
from typing import Iterable, List
class CustomList(list):
def __init__(self, *args: Iterable[int | float]):
if args == ():
super().__init__(*args)
elif all(isinstance(a, (int, float)) for a in args[0]):
super().__init__(*args)
else:
raise TypeError("CustomList instance can contain int and float datatypes only")
def __sub__(self, other: List[int | float] | "CustomList") -> "CustomList":
if isinstance(other, (self.__class__, list)):
result = CustomList()
for i in range(max(len(self), len(other))):
if i < len(self) and i < len(other):
result.append(self[i] - other[i])
elif i < len(self):
result.append(self[i])
else:
result.append(other[i])
return result
def __neg__(self):
result = CustomList()
for val in self:
result.append(-val)
return result
def __rsub__(self, other):
return - self.__sub__(other)
>>> [1, 2, 3] - CustomList([2, 4, 6])
[-1, -2, -3]