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
来处理。(见附件)