【问题标题】:Implementing sum() for custom datatype为自定义数据类型实现 sum()
【发布时间】:2020-03-13 22:20:27
【问题描述】:

据我了解,为了能够将sum() 投射到对象上,它必须是可迭代的,并且必须是“可添加的”,即它必须实现方法__iter____add__。但是,当我为我的班级 Point(只是一个示例)执行此操作时,这不起作用。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

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

    def __iter__(self):
        return self

    def __str__(self):
        return str((self.x, self.y))


print(Point(2, 2) + Point(1, 1))
>>> (3, 3)    # As expected; good!

points = [Point(0, 0), Point(2, 0), Point(0, 2), Point(2, 2)]
print(sum(points))    # Expect (4, 4)
>>> TypeError: unsupported operand type(s) for +: 'int' and 'Point'

如果我实现__radd____add__ 相同,那么当我尝试sum() 时会出现属性错误:

AttributeError: 'int' object has no attribute 'x'

基于错误,我的 Points 在某处被分隔为 ints,但我不确定在哪里。 感谢您的帮助。

【问题讨论】:

  • 请注意,sum 不需要用于非数字类型。不过,尚不完全清楚sum 将什么视为数字类型。 (例如,它适用于lists,但明确拒绝strs。)
  • 这不只是因为''.join() 是比sum() 更好的字符串连接替代方案吗?编辑,见this answer
  • 绝对是,虽然我不完全确定为什么不能实现 sum 来调用 join 本身,而不是引发异常。
  • 我倾向于同意,上述线程中的其他一些人也同意。

标签: python python-3.x overloading custom-data-type


【解决方案1】:

发生这种情况是因为sum 以默认值int 开头,而在执行sum(points) 时,真正发生的是sum 首先尝试添加0 + Point(0, 0),因此出现错误。如果您查看sum 上的帮助,这将变得非常明显,

关于内置模块内置函数 sum 的帮助:

总和(可迭代,开始=0,/) 返回一个“开始”值的总和(默认值:0)加上一个可迭代的数字

When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values and may
reject non-numeric types.

换行,

>>> print(sum(points))

>>> print(sum(points, Point(0, 0)))

【讨论】:

  • 很有趣,谢谢。我想知道为什么选择sum(sequence) 从 0 开始,而不是从左到右(或从右到左)添加元素。也许可以处理len(sequence) <= 1.
  • 我不太清楚为什么实现选择了那个。我必须检查:)
  • 0 只是默认的起始值,既可以处理空序列,也可以正常使用简单地将值相加。如果您愿意,可以传递不同的起始值。 sum(values, x) == x + sum(values)。例如,sum([[1], [2]], [3]) == [3] + sum([[1], [2]], []) == [3, 1, 2]
  • 是的,将起始值设为 0 是有意义的。有起始值更容易,因为通常可迭代的项目通常是数字,起始值不允许是字符串。
猜你喜欢
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 2023-03-29
  • 2022-12-14
  • 2014-07-06
  • 2011-02-04
  • 1970-01-01
  • 2018-10-05
相关资源
最近更新 更多