PYTHON是UNFAIR。它的治疗清单和具有偏倚的非清单变量

时间:2012-02-17 06:14:40

标签: python

使用以下示例代码:

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以不同的方式处理列表和变量?

5 个答案:

答案 0 :(得分:10)

不要将Python中的变量视为存储数据的命名框。把它们想象成你坚持物品的名牌。

在您的函数中,您将名称x粘贴在对象8上。这是一个本地名称,因此当函数结束时它会消失。在函数内部,本地名称x“阴影”(阻止访问)全局名称x,因此全局名称x不受分配的影响。它仍然指向对象5,当你在函数外打印时,这就是你得到的。

您不是更改名称mat在函数内引用的对象。而是改变(变异)指向的对象。方法调用,即使是更改对象的方法,也与赋值不同。没有创建本地名称mat,因此您正在改变在函数外部创建的同一对象。

这对于初学Python程序员来说是一个常见的陷阱,但它很容易理解,一旦理解,就不会对语言编程造成任何明显的困难。

你不明白的事实并没有使它成为“不公平”。 Python已经存在了二十多年。它由非常聪明的人设计,可能被全世界成千上万的程序员使用。如果Python在这个级别的基础上出现了问题,那么它现在已经修复了。

答案 1 :(得分:3)

变异和重新绑定是两种不同的操作。前者修改对象而不管它在哪里,而后者只修改本地名称,保持其他名称不变。

答案 2 :(得分:2)

添加功能执行以下操作:

  1. 打印c+b
  2. 的结果
  3. 在本地范围内创建一个新变量,引用值8
  4. 找到mat,然后调用成员函数append(c)
  5. 找到mat,然后调用成员函数append(b)
  6. 因此,matx都会继续引用之前引用的相同对象,但由于添加调用,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