📜  __rmul__ 在Python中

📅  最后修改于: 2022-05-13 01:55:34.188000             🧑  作者: Mango

__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]