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

Python 运算符重载多个操作数以返回类列表,python,operator-overloading,Python,Operator Overloading,如何在python中为重载添加的类编写代码,如下所示: 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] 也

如何在python中为重载添加的类编写代码,如下所示:

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的列表,每个“+”添加到列表中

问题是,从add函数返回的内容不是
A
类的实例。您可以围绕一个函数调用构造函数,并添加 如果这是您想要的,请将项目添加到列表中。您还需要检查该值是否不是list的实例,否则将返回
[[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]

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)
如果您想要直接列表连接,只需使用列表

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

问题在于,从add函数返回的内容不是
A
类的实例。您可以围绕一个函数调用构造函数,并添加 如果这是您想要的,请将项目添加到列表中。您还需要检查该值是否不是list的实例,否则将返回
[[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]

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)
如果您想要直接列表连接,只需使用列表

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

为了完成您想要完成的任务,您需要同时重载
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,还需要检查另一个值是否为type
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
,它调用列表的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,而不是
类的


这就是为什么您需要定义
\uuuu radd\uuuu
以使其使用
A
类的加法。

为了完成您试图完成的任务,您需要同时重载
\uuuu add\uuuu
\uu radd\uu
,并检查其他值是否为type
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
,它调用列表的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,而不是
A


这就是为什么您需要定义
\uuu radd\uuu
以使其使用
A
类的添加。

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

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]

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

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]

就像modesiit评论的那样,您的问题是add最初会返回一个列表。因此,在这之后,您会遇到错误,因为您试图添加一个列表和一个类a的对象。我不确定您为什么要这样做,但我做了以下操作,并得到了您预期的结果:

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

本质上,这将创建一个新的列表子类,该子类现在在列表对象本身上有一个value属性。现在所有的功能都和以前一样,没有重载。但是在这种情况下,返回值的类型仍然是list而不是A,这一事实仍然存在问题。如果您愿意,您可能会执行重载
\uuuuuu add\uuuuuu
之类的操作来调用与正常类似但稍后转换为A类型的super,但是您需要相应地调整
\uuuu init\uuuu
方法

就像modesiit评论的那样,您的问题是add最初会返回一个列表。因此,在这之后,您会遇到错误,因为您试图添加一个列表和一个类a的对象。我不确定您为什么要这样做,但我做了以下操作,并得到了您预期的结果:

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

本质上,这将创建一个新的列表子类,该子类现在在列表对象本身上有一个value属性。现在所有的功能都和以前一样,没有重载。但是在这种情况下,返回值的类型仍然是list而不是A,这一事实仍然存在问题。如果您愿意,您可能会执行重载
\uuuuuu add\uuuuuu
之类的操作来调用与正常类似但稍后转换为A类型的super,但是您需要相应地调整
\uuuu init\uuuu
方法

这是一个简洁的解决方案,我不熟悉radd!这是一个简洁的解决方案,我不熟悉radd!