【问题标题】:TypeError: unsupported operand type(s) for + when using sumTypeError:使用 sum 时 + 不支持的操作数类型
【发布时间】:2017-06-02 14:43:29
【问题描述】:

我有一个班级,我自己实现了__add__

class Point(namedtuple('Point', ['x', 'y', 'z'])):
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y, self.z + other.z)

添加按预期工作:

l = [Point(0,0,0), Point(0,1,2)]
s = l[0]
for a in l[1:]:
    s = s + a

但是当我使用内置 sum 时,我收到了一个错误:

s = sum(l)

TypeError: +: 'int' 和 'Point' 的操作数类型不受支持

我的代码有什么问题? sum 不使用__add__ 吗?我还应该覆盖什么?

【问题讨论】:

  • 我认为您正在寻找的是“radd”而不是“add”?

标签: python sum add


【解决方案1】:

sum 函数将其结果变量初始化为整数值 0:

sum(iterable[, start]) -> value

    Return the sum of an iterable of numbers (NOT strings) plus the value
    of parameter 'start' (which defaults to 0).

所以在 sum 内部,执行了加法 0 + Point(0,0,0),这是你的类不支持的。

要解决这个问题,请为start 传递一个合适的值:

s = sum(l, Point(0,0,0))

【讨论】:

  • 是来自官方文档吗?至少可以说这是相当误导。
  • @DeepSpace 这段摘自help(sum),不知道是不是跟文档一样。
  • 这似乎是一个可行的解决方法;你知道是否有一种方法可以在Point 类中 使加法的中性元素是Point(0,0,0)?
  • @sygi 不幸的是,我认为没有办法做到这一点。
  • @sygi 您可以尝试为 isinstance(other, int) and other == 0 添加 Point(0, 0, 0) 的情况定义加法(和 r-加法)?像这样: (... 用分号,因为显然我不能在这里做多行) ` def __add__(self, other): if isinstance(other, Point): return Point(self.x + other.x, self. y + other.y, self.z + other.z); elif isinstance(other, int) and other == 0: return self # === self + Point(0, 0, 0);否则:返回未实现; `
【解决方案2】:

您还可以覆盖__radd__() 函数:

def __radd__(self, other):
    return Point(self.x + other, self.y + other, self.z + other)

请注意,这必须在另外覆盖__add__()

【讨论】:

  • 我做到了,虽然我更喜欢__radd__ = __add__ :)
  • 注:要使其工作,您还需要实现将Point 添加到int (0)。
  • 我测试了答案中的版本,它没有任何添加就可以工作。代码有一个微小的区别,即你添加other而不是other.{x,y,z}
  • 是的,但它会以错误的方式改变行为 - 您将 Points 添加到每个坐标的 ints 中,结果是一个整数点:P(x=P(x=3, y=4), y=P(x=4, y=5))跨度>
猜你喜欢
  • 2020-02-29
  • 2011-03-08
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
  • 2012-12-26
相关资源
最近更新 更多