在Python中使用'__rsub__'方法的典型实例是什么?
What is a typical instance of using '__rsub__' method in Python?
当我 运行 进入 __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 expression x - y
, where y
is an instance of a class that has an __rsub__()
method, y.__rsub__(x)
is called if x.__sub__(y)
returns NotImplemented
.
我无法想象为什么需要该方法以及它在现实中的具体使用情况。
能否请您给我一个该方法有用的典型环境?
基本示例。你写你自己的 int
-like class:
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)
,return 没有错误,我们很好。
接下来我们看:
123 - FooInt(456)
Python 尝试调用 int.__sub__(123, FooInt(456))
,但 int
不知道如何处理 FooInt
和 returns NotImplemented
;它不知道 intvalue
有一个可以用于此目的的值。在这一点上,Python 不能只调用 FooInt.__sub__(FooInt(456), 123)
因为它不能假设减法是可交换的(事实上,在大多数数字系统中,减法在这种情况下是不可交换的,你可以' t只是交换运算符的左右两侧并得到正确的结果)。这就是 __rsub__
存在的原因;它允许您检查另一个 class 以了解处理操作的方法,同时告诉它两件事:
- 它在二元运算符的右侧(允许它正确处理交换性)
- 左边的项目不知道如何处理操作,所以这是最后一次纠正的机会
第二点也很重要。在实现 __xxx__
(左手运算符)时,您希望对识别的类型非常保守。如果您不确定您正在使用已知的具体类型和已知的正确处理程序,那么您不应该尝试处理未知类型;另一种类型可能知道如何正确地进行操作,所以你 return NotImplemented
让另一方处理它。当你实施 __rxxx__
时,你就是最后的机会;另一个人不知道该怎么做,所以你应该接受什么,有什么办法就尽力而为。您可以在 Implementing the arithmetic operations 上的 Python 文档中看到这一点; __xxx__
操作检查具体类型(对于 Fraction
,它检查 Fraction
、int
、float
和 complex
),而__rxxx__
操作员检查通用接口(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;假设是 subclass 将有更多信息来正确确定要做什么,因此它在执行操作时首先尝试。
当我 运行 进入 __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
-like class:
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)
,return 没有错误,我们很好。
接下来我们看:
123 - FooInt(456)
Python 尝试调用 int.__sub__(123, FooInt(456))
,但 int
不知道如何处理 FooInt
和 returns NotImplemented
;它不知道 intvalue
有一个可以用于此目的的值。在这一点上,Python 不能只调用 FooInt.__sub__(FooInt(456), 123)
因为它不能假设减法是可交换的(事实上,在大多数数字系统中,减法在这种情况下是不可交换的,你可以' t只是交换运算符的左右两侧并得到正确的结果)。这就是 __rsub__
存在的原因;它允许您检查另一个 class 以了解处理操作的方法,同时告诉它两件事:
- 它在二元运算符的右侧(允许它正确处理交换性)
- 左边的项目不知道如何处理操作,所以这是最后一次纠正的机会
第二点也很重要。在实现 __xxx__
(左手运算符)时,您希望对识别的类型非常保守。如果您不确定您正在使用已知的具体类型和已知的正确处理程序,那么您不应该尝试处理未知类型;另一种类型可能知道如何正确地进行操作,所以你 return NotImplemented
让另一方处理它。当你实施 __rxxx__
时,你就是最后的机会;另一个人不知道该怎么做,所以你应该接受什么,有什么办法就尽力而为。您可以在 Implementing the arithmetic operations 上的 Python 文档中看到这一点; __xxx__
操作检查具体类型(对于 Fraction
,它检查 Fraction
、int
、float
和 complex
),而__rxxx__
操作员检查通用接口(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;假设是 subclass 将有更多信息来正确确定要做什么,因此它在执行操作时首先尝试。