0

I just want to use the __add__ modifier, to use '+=' to easily add to elements of a classinstance:

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

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


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

The resulting problem will equal Noneafter the +=. Why? And how can I prevent that from happening?

P.S.: I have also tried implementing __iadd__ with no effect...

mrCarnivore
  • 4,638
  • 2
  • 12
  • 29

3 Answers3

4

You need to return the new state of the instance from __add__:

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

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

However, now you have a problem when using + on its own:

a = Problem()

b = a + 5

print (a)
print (b)

results in:

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

a and b are the same instance! We would expect b to be different from a, with an extra object in its lItems.

This is why you want to use the __iadd__ method. It only works on +=:

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

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

... and using + results in an error, as it should.

Markus
  • 3,447
  • 3
  • 24
  • 26
Colin Ricardo
  • 16,488
  • 11
  • 47
  • 80
0

After your append operation, you need to return the object.

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

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

Example

>>> problem = Problem()
>>> problem += 'text'
>>> problem.lItems
['text']
>>> problem += 'foobar'
>>> problem.lItems
['text', 'foobar']
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
-2

Making __add__ return self does the trick:

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)

outputs :

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

EDIT: You should consider the use of __iadd__ special method instead.

bonnal-enzo
  • 1,165
  • 9
  • 19