当我遇到 __rsub__
时,我正在自学 Python方法。虽然我可以找到 explanation on the method in the official documentation :
These methods are called to implement the binary arithmetic operations (
+
,-
,*
,/
,//
,%
,divmod()
,pow()
,**
,<<
,>>
,&
,^
,|
) with reflected (swapped) operands. These functions are only called if the left operand does not support the corresponding operation and the operands are of different types. For instance, to evaluate the expressionx - y
, wherey
is an instance of a class that has an__rsub__()
method,y.__rsub__(x)
is called ifx.__sub__(y)
returnsNotImplemented
.
我无法想象为什么需要该方法以及它在现实中的具体使用情况。
能否请您给我一个该方法有用的典型环境?
最佳答案
基本示例。您编写自己的 int
类:
class FooInt:
... other stuff elided ...
def __sub__(self, other):
if isinstance(other, FooInt):
return self.__class__(self.intvalue - other.intvalue)
elif isinstance(other, int):
return self.__class__(self.intvalue - other)
else:
return NotImplemented
现在您有了执行以下操作的代码:
FooInt(123) - 456
这很好用; Python 在左侧看到 FooInt
,看到它有 __sub__
,然后调用 FooInt.__sub__(FooInt(123), 456)
返回没有错误,我们很好。
接下来我们看:
123 - FooInt(456)
Python 尝试调用 int.__sub__(123, FooInt(456))
,但是 int
不知道如何处理 FooInt
,并返回 NotImplemented
;它不知道 intvalue
有一个可以用于此目的的值。此时,Python 不能只调用 FooInt.__sub__(FooInt(456), 123)
因为它不能假设减法是可交换的(事实上,在大多数数值系统中,减法是在这种情况下不是可交换的,您不能只交换运算符的右侧和左侧并获得正确的结果)。这就是 __rsub__
存在的原因;它允许您在告诉其他类两件事的同时检查其他类以寻找处理操作的方法:
- 它在二元运算符的右侧(允许它正确处理交换性)
- 左边的项目不知道如何处理操作,所以这是最后一次做对的机会
第二点也很重要。在实现 __xxx__
(左手运算符)时,您希望对识别的类型非常保守。如果您不确定您正在使用已知的具体类型和已知的正确处理程序,那么您不应该尝试处理未知类型;另一个类型可能知道如何正确地执行操作,因此您返回 NotImplemented
并让另一方处理它。当你实现 __rxxx__
时,你是最后的机会;另一个人不知道该怎么做,所以你应该接受什么,有什么办法就尽力而为。您可以在 Implementing the arithmetic operations 上的 Python 文档中看到这一点; __xxx__
操作检查具体类型(对于 Fraction
,它检查 Fraction
、int
、float
和 complex
),而 __rxxx__
运算符检查通用接口(interface)(numbers.Integral
、numbers.Rational
、numbers.Real
等)。
我忽略了相对重要的一点:If the class on the right side is a subclass of the class on the left, it has its reflected __rxxx__
method called first;假设子类将有更多信息来正确确定要做什么,因此它在执行操作时首先尝试。
关于python - 在 Python 中使用 '__rsub__' 方法的典型实例是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35736193/