实现__add__魔术方法以允许`sum`对对象进行操作

时间:2017-07-23 19:04:16

标签: python

我正在使用Foo方法定义课程__add__

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

    def __add__(self, other):
        return self.data + other.data

data属性仅包含字符串

最终目标是将Foo个对象的列表/可迭代传递给求和方法以连接字符串:

In [580]: s = [Foo('foo'), Foo('bar'), Foo('baz')] 

In [581]: sum(s)

预期:

foobarbaz

实际值:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-581-4c1cdc765951> in <module>()
----> 1 sum(s)

TypeError: unsupported operand type(s) for +: 'int' and 'Foo'

我认为sum调用object.__add__将两种方法加在一起。我知道我可以用另一种方式解决(可能使用functools.reduce)但是有没有办法让我可以使用sum

编辑:忘记提及,试过这个:

In [582]: sum(s, Foo(''))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-582-e3eeba9a6d93> in <module>()
----> 1 sum(s, Foo(''))

TypeError: Can't convert 'Foo' object to str implicitly

2 个答案:

答案 0 :(得分:3)

您需要将初始值传递给sum。由于您的课程仅支持添加到同一课程的其他实例,因此您必须指定&#34;空&#34; instance作为初始值:

sum(s, Foo(''))

但是,您的类也有一个问题:它只允许将Foo实例添加到其他Foo实例,但添加返回一个字符串,而不是Foo实例。所以你不能添加两个以上的Foos,甚至是#34;手动&#34;:

>>> Foo('a') + Foo('b') + Foo('c')
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    Foo('a') + Foo('b') + Foo('c')
TypeError: must be str, not Foo

要解决此问题,您需要让__add__返回Foo:

def __add__(self, other):
    return Foo(self.data + other.data)

然后,当您执行sum(s, Foo(''))时,您将得到的不是字符串foobarbaz,而是.data属性为'foobarbaz'的Foo实例。

答案 1 :(得分:1)

__add__必须返回Foo(self.data + other.data)

根据经验,__methods__应返回type(self)类型的对象,尽管并非总是如此。例如。您希望Int + IntFloat + Float返回什么?