Strange behaviour when inheriting from a list in python

坚强是说给别人听的谎言 提交于 2020-01-02 23:15:24

问题


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?


回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/21838848/strange-behaviour-when-inheriting-from-a-list-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!