PYTHON是UNFAIR。

PYTHON is UNFAIR. Its treating list and a non list variable with partiality

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
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

EDOCX1[0]被附加了,但是为什么x不改变呢?为什么python处理列表和变量的方式不同?


不要将python中的变量视为存储数据的命名框。把它们当作你贴在物体上的名字标签。

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

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

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

你不懂的事实并不意味着它"不公平",Python已经存在了二十多年了。它是由非常聪明的人设计的,可能被世界上成千上万的程序员使用。如果在这个基本级别上,Python有什么问题的话,那么到目前为止它已经被修复了。


突变和再绑定是两种不同的操作。前者修改对象,而不管对象在哪里,后者只修改本地名称,不影响其他名称。


这里的add函数执行以下操作:

  • 打印EDOCX1[0]的结果
  • 在本地范围内创建一个新变量,引用值8
  • 定位mat,调用成员函数append(c)
  • 定位mat,调用成员函数append(b)
  • 因此,matx继续引用它们之前所引用的相同对象,但是,mat表示的列表由于add调用而发生了更改。


    列表是可变的,而数字不是。这里有更多的例子http://inst.eecs.berkeley.edu/~selfspace/cs9honline/q2/mutation.html


    在add()函数内分配给x将创建一个新变量。这是Python的怪癖之一。

    这里有一个解决方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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