使用radd方法在类之间添加

时间:2012-02-03 09:59:12

标签: python-3.x

class exampleclass1:
    def __init__(self, data):
        self.data = data

    def __add__(self, other):
        if isinstance(other, int):
            print('blabla')


class exampleclass2:
    def __init__(self, data):
        self.data = data

    def __add__(self, other):
        if isinstance(other, exampleclass1):
            print("it's working yay")

    __radd__ = __add__

a = exampleclass1('q')

b = exampleclass2('w')

a+b

我的问题是:我有两个不同的类,我想在一个类中定义它们的添加,并为该类定义add和radd(在这个例子中是exampleclass2。我不想创建一个add方法,适用于exampleclass1以添加exampleclass2。

现在它只是忽略了它。我也试图提出错误,但这也没有用。非常高兴能得到我的帮助! :)

3 个答案:

答案 0 :(得分:15)

__radd__仅在左对象没有__add__方法时调用,或者该方法不知道如何添加两个对象(通过返回NotImplemented标记它)。这两个类都有一个__add__方法,它不返回NotImplemented。因此永远不会调用__radd__方法。

答案 1 :(得分:2)

  

只有左操作数才会调用这些函数__radd__   不支持相应的操作和操作数   不同种类。例如,

class X:
  def __init__(self, num):
    self.num = num
class Y:
  def __init__(self, num):
    self.num = num

  def __radd__(self, other_obj):
    return Y(self.num+other_obj.num)

  def __str__(self):
    return str(self.num)
>>> x = X(2)
>>> y = Y(3)
>>> print(x+y)
5
>>>
>>> print(y+x)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-60-9d7469decd6e> in <module>()
----> 1 print(y+x)

TypeError: unsupported operand type(s) for +: 'Y' and 'X'

答案 2 :(得分:1)

假设您要实现一个要通过运算符重载来充当数字的类。因此,您在类中实现了 add ,现在myobj + 4之类的表达式可以根据需要工作并产生一些结果。这是因为myobj + 4被解释为myobj.__add__(4),并且您的自定义方法可以执行将4加到自定义类中的任何操作。

但是,像4 + myobj这样的表达式实际上是(4).__add__(myobj)呢? 4是Python内置类型的实例,其 add 方法对您的新类型一无所知,因此它将返回特殊值NotImplemented。 (解释器识别出来自 add 的特殊值,并引发TypeError异常,该异常会杀死您的程序,这是您实际看到的行为,而不是返回的特殊值。)

如果myobj + 4有效,但4 + myobj无效,则会使操作员超载。那是任意的和限制性的-加法应该是可交换的。输入__radd__。 Python首先会尝试(4).__add__(myobj),如果返回NotImplemented,Python将检查右侧操作数是否实现 radd ,如果这样做,它将调用myobj.__radd__(4)而不是引发TypeError。现在,一切都可以照常进行,因为您的班级可以处理情况并实现您的行为,而不是内置类型的 add ,它是固定的并且对您的班级不了解。

示例:

class X:
    
    def __init__(self, num):
        self.num = num

    def __str__(self):
        return str(self.num)

    def __add__(self, other):
        return self.num + other.num
    
    __radd__ = __add__


class Y:

    def __init__(self, num):
        self.num = num

    def __str__(self):
        return str(self.num)


x = X(5)
y = Y(10)

print(x+y)

print(y+x)