从python中的列表继承时的奇怪行为 [英] Strange behaviour when inheriting from a list in python
问题描述
我最近对于继承缠身,我对以下行为感到困惑:
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?
推荐答案
p>因为这是就地操作符的工作方式。
Because that's how in-place operators work.
self = self + [thing]
并将其放入局部变量 self
,覆盖传递的一个。但它不修改对象本身。在内部,它 self = self .__ add __([thing])
。
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,就地修改列表。在内部,它首先尝试 self = self .__ iadd __([thing])
。 iadd
代表inplace add。只要不存在, 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.
区别是 __ add __()
总是创建一个新对象,并保持其他对象不变。 __ iadd __()
,但是,应该首先尝试修改其操作的对象。在这种情况下,它返回它,使得不发生对象的改变,即。 e。 self
是指与之前相同的对象。只有如果这是不可能的,它会返回一个新的,然后分配。
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.
这篇关于从python中的列表继承时的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!