__rmul__ 在Python中
对于每个运算符符号,都有一个底层机制。这种底层机制是一种特殊的方法,将在运算符操作期间调用。这种特殊的方法被称为魔法方法。对于像 +、-、*、/ 这样的算术计算,我们需要 2 个操作数来执行运算符功能。
例子:
‘+’ ? ‘__add__’ method
‘_’ ? ‘__sub__’ method
‘*’ ? ‘__mul__’ method
由于本文仅限于乘法功能,我们将在此处了解乘法过程。要执行乘法功能,我们必须将运算符符号绑定到左/右操作数。之前,去__rmul__
方法,我们将看到__mul__
方法,它有助于我们形象地理解乘法功能。
__mul__()
让我们看一个表达式x*y
,其中 x 是类 A 的一个实例。要执行__mul__
方法,运算符会查看左操作数 (x) 的类是否存在 __mul__ 即,运算符(*) 将检查该类A 表示其中存在' __mul__
' 方法。如果它有__mul__
方法,它会调用x.__mul__(y)
。否则,它会抛出 ' TypeError: unsupported operands ' 错误消息。
示例 1:
class Foo(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Foo [% s]" % self.val
class Bar(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Bar [% s]" % self.val
# Driver Code
f = Foo(5)
b = Bar(6)
print(f * b)
输出:
TypeError, unsupported operand type(s) for *: 'Foo' and 'Bar'
在上面的例子中,第一个操作数是 f 和它的类 Foo()。由于 Foo() 没有__mul__
方法,它不知道如何乘法。因此,它将显示 TypeError 消息。如果我们检查另一个类 Bar(),即使它没有__mul__
方法。因此,即使我们将乘法反转为 (b*f),它也会抛出相同的错误
示例 2:让我们在 Foo 类中添加 __mul__ 方法。
class Foo(object):
def __init__(self, val):
self.val = val
def __mul__(self, other):
return Foo(self.val * other.val)
def __str__(self):
return "Foo [% s]" % self.val
class Bar(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Bar [% s]" % self.val
# Driver Code
f = Foo(5)
b = Bar(6)
print(f * b)
输出:
Foo 30
正如已经提到的,默认情况下,运算符会查看左操作数的类,并在此处找到 __mul__ 方法。现在它知道该做什么并产生 30 f.__mul__(b) = 5.__mul__(6)
。如果我们将乘法反转为 (b*f),它会再次引发问题,因为它会查看没有任何__mul__
方法的左操作数的类(Bar())。 b.__mul__(f)
将引发问题,因为 b 的类 Bar() 没有__mul__
方法。
__rmul__
__mul__
和__rmul__
之间的细微差别是,运算符在左操作数中查找__mul__
而在右操作数中查找__rmul__
。例如,x*y。运算符在 y 的类定义中查找__rmul__
方法。如果找到__rmul__
方法,它将显示结果,否则抛出TypeError 错误消息
示例 1:让我们以上面的示例稍作修改。
class Foo(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Foo [% s]" % self.val
class Bar(object):
def __init__(self, val):
self.val = val
def __rmul__(self, other):
return Bar(self.val * other.val)
def __str__(self):
return "Bar [% s]" % self.val
# Driver code
f = Foo(5)
b = Bar(6)
print(f * b)
输出:
Bar 30
在上面的例子中,它假设 f*b as b.__rmul__(f)
因为__rmul__
方法存在于实例 b 的 Bar() 类中。如果我们将乘法反转为 (b*f)。符号将是f.__rmul__(b)
。如果它没有__rmul__
方法,它就无法理解要注释的内容并抛出 TypeError 消息。
这些类型的运算符,需要 2 个操作数,默认情况下会同时携带__mul__
和__rmul__
方法。要执行正乘和反向乘法的乘法,请参见下面的示例。
示例 2:
class Foo(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Foo [% s]" % self.val
class Bar(object):
def __init__(self, val):
self.val = val
def __rmul__(self, other):
return Bar(self.val * other.val)
def __mul__(self, other):
return self.__rmul__(other)
def __str__(self):
return "Bar [% s]" % self.val
# Driver Code
f = Foo(5)
b = Bar(6)
print(b * f)
print(f * b)
输出:
Bar [30]
Bar [30]