使用以下示例代码:
mat = []
x = 5
def add(c,b):
print c+b
x = 8
mat.append(c)
mat.append(b)
add(5,6)
add(8,9)
print mat
print x
mat
正在追加,但为什么x不变?为什么python以不同的方式处理列表和变量?
答案 0 :(得分:10)
不要将Python中的变量视为存储数据的命名框。把它们想象成你坚持物品的名牌。
在您的函数中,您将名称x
粘贴在对象8
上。这是一个本地名称,因此当函数结束时它会消失。在函数内部,本地名称x
“阴影”(阻止访问)全局名称x
,因此全局名称x
不受分配的影响。它仍然指向对象5
,当你在函数外打印时,这就是你得到的。
您不是更改名称mat
在函数内引用的对象。而是改变(变异)指向的对象。方法调用,即使是更改对象的方法,也与赋值不同。没有创建本地名称mat
,因此您正在改变在函数外部创建的同一对象。
这对于初学Python程序员来说是一个常见的陷阱,但它很容易理解,一旦理解,就不会对语言编程造成任何明显的困难。
你不明白的事实并没有使它成为“不公平”。 Python已经存在了二十多年。它由非常聪明的人设计,可能被全世界成千上万的程序员使用。如果Python在这个级别的基础上出现了问题,那么它现在已经修复了。
答案 1 :(得分:3)
变异和重新绑定是两种不同的操作。前者修改对象而不管它在哪里,而后者只修改本地名称,保持其他名称不变。
答案 2 :(得分:2)
添加功能执行以下操作:
c+b
8
。mat
,然后调用成员函数append(c)
mat
,然后调用成员函数append(b)
因此,mat
和x
都会继续引用之前引用的相同对象,但由于添加调用,mat
所代表的列表已更改。
答案 3 :(得分:1)
列表是可变的,而数字则不是。更多示例http://inst.eecs.berkeley.edu/~selfpace/cs9honline/Q2/mutation.html
答案 4 :(得分:0)
在add()函数中分配x会创建一个新变量。这是Python的怪癖之一。
这是一种解决方法:
mat = []
x = 5
def add(c,b):
global x # do not define a local 'x'
print c+b
x = 8
mat.append(c)
mat.append(b)
add(5,6)
add(8,9)
print mat
print x