我在这里有这个功能,我正在努力弄清楚输出是如何从这里得到的。任何帮助,将不胜感激。谢谢!
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']
答案 0 :(得分:2)
您看到的问题是,在do_that
函数中,您从x
和y
获得self._foo
和self._bar
。您修改两个局部变量。但是当您再次打印出来时,只有self._bar
发生了变化。
原因是在python中,list
类型是可变的(可以更改),int
类型是不可变的(并且只能被替换)。
这意味着当您获得y
到self._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']