PYTHON是不公平的。它的处理列表和一个带有偏好的非列表变量

PYTHON是不公平的。它的处理列表和一个带有偏好的非列表变量,python,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以不同的方式处理列表和变量?变异和重新绑定是两种不同的操作。前者修改对象,而不管它可能在哪里,后者只修改本地名称,而保留其他名称不变。那里的

使用下面的示例代码:

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

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

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

  • 打印
    c+b的结果
  • 参考值
    8
    ,在本地范围内创建一个新变量
  • 找到
    mat
    ,并调用成员函数
    append(c)
  • 找到
    mat
    ,并调用成员函数
    append(b)

  • 因此,
    mat
    x
    都继续引用它们以前引用的相同对象,但是由于add调用,
    mat
    表示的列表发生了更改。

    不要将Python中的变量视为存储数据的命名框。将它们视为粘贴在对象上的名称标签

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

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

    这是初级Python程序员的常见陷阱,但它很容易理解,一旦理解,就不会给该语言的编程带来任何重大困难


    不理解某些东西并不意味着它“不公平”。Python已经存在了二十多年。它是由非常聪明的人设计的,世界上可能有成千上万的程序员在使用它。如果Python在这个基本级别上出现了问题,那么现在应该已经解决了。

    在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
    

    列表是可变的,而数字不是。这里有更多的例子

    请使用代码格式、正确的拼写、正确的语法等。您正在以不同的方式对待它们。。也许你是不公平的;)rtfm如果您自己不这样对待它们,您希望python如何同样对待它们?你变异了
    mat
    ,但给(一个新的)
    x
    分配了新的东西。尝试在函数中使用
    mat=[8]
    而不是
    mat.append
    ,您会发现现在列表没有任何不同。任何变异都会继续,任何变化都不会。我同意python是由专家和聪明人设计的最好的语言之一。我同意你的解释。但我的问题是mat在嵌套函数中是如何可见的?如果垫子是可见的,那么x应该是可见的吗?Python应该是合理的。@surya,x是可见的-直到您通过创建一个局部变量(也称为x)来隐藏它。如果您使用mat=[c,b],您会在那里看到相同的行为。@Dave,x在add(c,b)函数中不可见。没有指定8,我试图打印它。这导致了一场灾难traceback@surya您使用的是什么版本的python?因为这绝对不是我在2.7中得到的行为。它快乐地打印x。我可以得到回溯的唯一方法是,如果我尝试打印一个新变量,在这种情况下,它会抛出一个NameError:未定义全局名称“y”。如果存在该名称的全局变量,它会打印它。当您尝试类似于
    x+=1
    的操作时,将出现
    UnboundLocalError
    。这是一个小问题,可以说是语言中的一个缺陷,但可以通过事先调用
    global x
    来处理。(见附件)