从python中的列表继承时的奇怪行为 [英] Strange behaviour when inheriting from a list in python

查看:135
本文介绍了从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆