在这个代码示例中,[' boo there']来自何处?

时间:2018-03-18 04:59:43

标签: python

我在这里有这个功能,我正在努力弄清楚输出是如何从这里得到的。任何帮助,将不胜感激。谢谢!

class A:
    def __init__(self, a: int, b: [str]):
        self._foo = a
        self._bar = b

    def get_foo(self):
        return self._foo

    def get_bar(self):
        return self._bar



    def do_that(given: A):
        x = given.get_foo()
        x += 10
        y = given.get_bar()

        y[0] += ' there'

        y = ['cool']

        given = A(-10, ['bye'])


x = A(1, ['boo'])
print(x.get_foo())
print(x.get_bar())
do_that(x)
print(x.get_foo())
print(x.get_bar())

有人可以解释为什么这是输出? [' boo there']来自哪里,1就在那之前?

1
['boo']
1
['boo there']

2 个答案:

答案 0 :(得分:2)

您看到的问题是,在do_that函数中,您从xy获得self._fooself._bar。您修改两个局部变量。但是当您再次打印出来时,只有self._bar发生了变化。

原因是在python中,list类型是可变的(可以更改),int类型是不可变的(并且只能被替换)。

这意味着当您获得yself._bar并将"there"添加到元素[0]时,它实际上会更改self._bar所持有的列表值} attribute。

但由于self._foo只是一个不可变的值类型,因此将其分配给变量x并更改x只会导致x更改,而不是原始self._foo 1}}。

如果要更改实例属性,正确的编程会让你说self._foo += 10

答案 1 :(得分:2)

当您在y = given.get_bar()方法中致电do_that()时,get_bar()实际上会返回_bar列表引用的引用。因为列表是可变的所以它通过引用传递。

当您执行操作y[0] += ' there'时,它实际上会更改_bar列表,因为y是_bar的引用,并且其可变并变为['boo there']。但是当你执行y = ['cool']时,它实际上会创建一个新的列表引用,因此_bar之前的引用丢失了。所以它不会再改变_bar

在您致电do_that()后从x.get_bar()方法返回后,结果为['boo there']