从python中的列表继承时的奇怪行为

时间:2014-02-17 20:39:49

标签: python class inheritance

我最近正在摆弄遗产,我对以下行为感到有些困惑:

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]

为什么就地方法method2有效,但第一种方法不起作用?

2 个答案:

答案 0 :(得分:2)

因为这就是就地操作员的工作方式。

self = self + [thing]创建一个新列表并将其放入局部变量self中,覆盖传递的列表。但它不会修改对象本身。在内部,它self = self.__add__([thing])

self += [thing],OTOH,就地修改列表。在内部,它首先尝试self = self.__iadd__([thing])iadd代表“inplace add”。只有在不存在的情况下,才会调用self = self.__add__([thing])

不同之处在于__add__()始终会创建一个新对象并保持其他对象不受影响。但是,__iadd__()应该首先尝试修改它所操作的对象。在这种情况下,它返回它,以便不发生对象的更改,i。即self指的是与以前相同的对象。只有在不可能的情况下,它才会返回一个新的,然后进行分配。

答案 1 :(得分:0)

list.__add__()(内置+运算符)会创建一个新列表,而list.__iadd__()(内置+=运算符)会修改列表。