运算符重载多个操作数以返回类列表

时间:2017-11-07 01:27:26

标签: python operator-overloading

如何在python中编写一个重载add的类的代码,如下所示:

class A:
  def __init__(self,value):
    self.value = value

  def __add__(self,other):
    return [self.value, other.value]

这适用于两个操作数,但如何使其适用于多个操作数,所以:

a1 = A(10)
a2 = A(20)
a3 = A(30)
print a1 + a2 + a3

应该返回[a1,a2,a3]

这就是add函数应该返回A类的列表,每个'+'添加到列表

4 个答案:

答案 0 :(得分:2)

为了达到您要完成的目标,您需要重载__add____radd__,并检查其他值是否为list,将self.value附加到该列表。

class A:
  def __init__(self, value):
    self.value = value

  def __add__(self, other):
    return [self.value, other.value]

  def __radd__(self, other):
    if isinstance(other, list):
      return other + [self.value]
    return [other, self.value]

a1 = A(10)
a2 = A(20)
a3 = A(30)
print (a1 + a2 + a3)
# [10, 20, 30]

为什么你的工作不起作用的原因是:

print a1 + a2 + a3

首先评估a1 + a2,得到正确答案[10, 20]。但是紧接着,下一个运行的操作是[10, 20] + a3,它会调用列表的__add__,而不是A类。

这就是为什么你需要定义__radd__以使其使用A类的补充。

答案 1 :(得分:0)

问题是,从add函数返回的内容不是A类的实例。你可以在A周围调用构造函数,然后添加 列表中的项目,如果这是你想要的。您还需要检查该值是否不是列表实例,否则您将返回[[10, 20,] 30]

class A:
    def __init__(self,value):
        self.value = value
    def __add__(self,other):
        if isinstance(self.value, list):
            vals =[val for val in self.value]
            vals.append(other.value)
            return A(vals)
        return A([self.value, other.value])
    def __str__(self):
        return str(self.value)


a1 = A(10)
a2 = A(20)
a3 = A(30)
print(a1 + a2 + a3)

打印[10, 20, 30]

如果您想要直接列表连接,只需使用列表?

a1 = [10]
a2 = [20]
a3 = [30]
print a1 + a2 + a3

答案 2 :(得分:0)

你可以像这样分解重载的逻辑:

a1 +  (a2 + a3)
      separate instance

您可以这样实现:

class A:
   def __init__(self, val):
      self.val = val
      self.cummulative = [val]
   def flatten(self, val):
       if isinstance(val, int):
            yield val
       else:
           for i in val:
              for b in self.flatten(i):
                  yield b
   def __add__(self, instance):
      self.cummulative.append(instance.cummulative)
      return A(self.cummulative)
   def __str__(self):
       return repr(list(self.flatten(self.cummulative)))

a1 = A(40)
a2 = A(50)
a3 = A(60)
val = a1+a2+a3
print(val)

输出:

[40, 50, 60]

答案 3 :(得分:0)

就像modelsiit评论的那样,您的问题是添加最初会返回一个列表。所以在那之后你遇到了错误,因为你正在尝试添加一个列表和一个A类的对象。我不知道你为什么要这样做,但我做了以下并得到了你的预期结果:< / p>

class A(list):
    def __init__(self, value):
        self.value = value
        super(A, self).__init__([value])

本质上,这会创建一个新的列表子类,现在在列表对象本身上有一个value属性。现在一切都像以前一样完全没有超载。在这种情况下,你仍然会遇到问题,因为返回的值是类型列表而不是类型A的事实。你最终可能会像重载__add__一样调用超级正常但是强制转换如果您愿意,可以在以后输入类型A,但需要相应地调整__init__方法

相关问题