【问题标题】:`+=` leads to `none` with class instance [duplicate]`+=` 导致类实例为 `none` [重复]
【发布时间】:2018-10-01 03:28:07
【问题描述】:

我只想使用 __add__ 修饰符,使用 '+=' 轻松添加到类实例的元素:

class Problem:
    def __init__(self):
        self.lItems = []

    def __add__(self, other):
        self.lItems.append(other)


problem = Problem()
problem += 'text'
print(problem)

+= 之后,产生的问题将等于None。为什么?我怎样才能防止这种情况发生?

P.S.:我也尝试过实现__iadd__,但没有任何效果......

【问题讨论】:

  • __add__ 需要返回一个值。
  • 即使def __add__(self, other): return self.lItems.append(other) 也不起作用...
  • 否,因为append 本身返回无。

标签: python python-3.x class operator-overloading


【解决方案1】:

你需要从__add__返回实例的新状态:

class Problem:
    def __init__(self):
        self.lItems = []

    def __add__(self, other):
        self.lItems.append(other)
        return self

但是,现在您在单独使用 + 时会遇到问题:

a = Problem()

b = a + 5

print (a)
print (b)

结果:

<__main__.Problem instance at 0x0022BE40>
<__main__.Problem instance at 0x0022BE40>

ab 是同一个实例!我们希望ba 不同,在其lItems 中有一个额外的对象。

这就是您要使用__iadd__ 方法的原因。它仅适用于+=

class Problem:
    def __init__(self):
        self.lItems = []

    def __iadd__(self, other):
        self.lItems.append(other)
        return self

... 并且使用 + 会导致错误,这是应该的。

【讨论】:

    【解决方案2】:

    append 操作后,您需要return 对象。

    class Problem:
        def __init__(self):
            self.lItems = []
    
        def __iadd__(self, other):
            self.lItems.append(other)
            return self
    

    例子

    >>> problem = Problem()
    >>> problem += 'text'
    >>> problem.lItems
    ['text']
    >>> problem += 'foobar'
    >>> problem.lItems
    ['text', 'foobar']
    

    【讨论】:

      【解决方案3】:

      __add__ 返回self 就行了:

      class Problem:
          def __init__(self):
              self.lItems = []
      
          def __add__(self, other):
              self.lItems.append(other)
              return self
      
      
      problem = Problem()
      problem += 'text'
      print(problem)
      print(problem.lItems)
      

      输出:

      <__main__.Problem object at 0x04BBDCD0>
      ['text']
      

      编辑: 您应该考虑改用__iadd__ special method

      【讨论】:

        猜你喜欢
        • 2019-04-16
        • 1970-01-01
        • 2013-11-12
        • 2012-04-04
        • 2014-12-04
        • 2011-10-08
        • 1970-01-01
        • 1970-01-01
        • 2023-02-12
        相关资源
        最近更新 更多