我最近在摆弄继承,对以下行为感到有些困惑:
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
有效,但第一个方法无效?
因为这就是就地操作员的工作方式。
self = self + [thing]
创建一个新列表并将其放入局部变量中self
,以覆盖传递的列表。但是它不会修改对象本身。在内部,它可以self = self.__add__([thing])
。
self += [thing]
OTOH可以就地修改列表。内部首先尝试self = self.__iadd__([thing])
。iadd
代表“就地添加”。仅当不存在时才self = self.__add__([thing])
被调用。
不同之处在于,__add__()
总是创建一个新对象,而其他对象保持不变。__iadd__()
但是,应该首先尝试对其进行操作的对象进行修改。在这种情况下,它将返回它,这样就不会发生对象更改,即self
与以前引用相同的对象。仅当这不可能时,它会返回一个新的,然后分配给它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句