1

I was fiddling around with inheritance recently and I'm a little confused by the behaviour of the following:

class Foo(list):

    def method(self, thing):
        new = self + [thing]
        print(new)
        self = new
        print(self)

    def method2(self, thing):
        self += [thing]

>>> f = Foo([1, 2, 3, 4, 5])
>>> f.method(10)
[1, 2, 3, 4, 5, 10]
[1, 2, 3, 4, 5, 10]
>>> f
[1, 2, 3, 4, 5]
>>> f.method2(10)
>>> f
[1, 2, 3, 4, 5, 10]

Why does the in-place method method2 work but the first one doesn't?

2 Answers 2

2

Because that's how in-place operators work.

self = self + [thing] creates a new list and put it into the local variable self, overriding the passed one. But it doesn't modify the object itself. Internally, it does self = self.__add__([thing]).

self += [thing], OTOH, modifies the list in-place. Internally it tries self = self.__iadd__([thing]) first. iadd stands for "inplace add". Only if that doesn't exist, self = self.__add__([thing]) is called.

The difference is that __add__() always creates a new object and leaves the others untouched. __iadd__(), however, is supposed to try first to modify the object it operates on. In this case, it returns it so that no change of object occurs, i. e. self refers to the same object as before. Only if this is not possible, it returns a new one which is then assigned.

Sign up to request clarification or add additional context in comments.

Comments

0

list.__add__() (the + operator builtin) creates a new list, while list.__iadd__() (the += operator builtin) modifies the list in place.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.