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处理列表和变量的方式不同?
- 请使用代码格式、正确的拼写、正确的语法等。
- stackoverflow.com/questions/146359/python-scope
- 你对待他们的方式不同……也许你是不公平的人;)RTFM
- 如果你不自己对待它们,你怎么希望Python也同样对待它们呢?你突变了mat,但给(新的)x赋予了新的东西。尝试在函数内部使用mat = [8],而不是在函数内部使用mat.append,您会发现现在列表的处理方式没有任何不同。任何突变都会继续进行,而任何一种变异都不会发生。
不要将python中的变量视为存储数据的命名框。把它们当作你贴在物体上的名字标签。
在函数中,您将名称x粘贴在对象8上。这是一个本地名称,所以当函数结束时它就消失了。在函数内部,本地名称x为"shadows"(阻止访问)全局名称x,因此全局名称x不受分配的影响。它仍然指向对象5,当您在函数外部打印它时,这就是您得到的。
您没有更改函数内部名称mat所指的对象。相反,您正在改变(改变)所指向的对象。方法调用(即使是更改对象的方法调用)与赋值不同。没有创建本地名称mat,因此您要改变在函数外部创建的同一对象。
对于刚开始的Python程序员来说,这是一个常见的陷阱,但是它很容易理解,一旦被理解,就不会对语言编程造成任何显著的困难。
你不懂的事实并不意味着它"不公平",Python已经存在了二十多年了。它是由非常聪明的人设计的,可能被世界上成千上万的程序员使用。如果在这个基本级别上,Python有什么问题的话,那么到目前为止它已经被修复了。
- 我同意Python是专家和聪明人设计的最好的语言之一。我同意你的解释。但我的问题是mat在嵌套函数中是如何可见的?如果垫子可见,那么应该是x?Python应该是合理的。
- @surya,x是可见的-直到你通过创建一个局部变量(也叫x)来隐藏它。如果你做了mat=[c,b]你会看到同样的行为。
- @dave,x在函数add(c,b)中不可见。没有指定8,我试图打印它。它导致了回溯
- @Surya您使用的是什么版本的python?因为这绝对不是我用2.7得到的行为。它很乐意打印X。唯一的方法是,如果我尝试打印一个新的变量,在这种情况下,它会抛出一个名称错误:全局名称"y"没有定义。如果有一个同名的全局变量,它就会打印出来。
- 当你尝试类似于x += 1的东西时,会有一个UnboundLocalError。这是一个小问题,可以说是语言中的一个缺陷,但可以通过提前调用global x来处理。(见此处)
突变和再绑定是两种不同的操作。前者修改对象,而不管对象在哪里,后者只修改本地名称,不影响其他名称。
这里的add函数执行以下操作:
打印EDOCX1[0]的结果
在本地范围内创建一个新变量,引用值8。
定位mat,调用成员函数append(c)。
定位mat,调用成员函数append(b)。
因此,mat和x继续引用它们之前所引用的相同对象,但是,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 |