Python-列表变量的范围
我希望能更好地理解,为什么不在函数fct中将列表c声明为全局的情况下,它还能工作?变量a的情况并非如此Python-列表变量的范围,python,list,variables,scope,Python,List,Variables,Scope,我希望能更好地理解,为什么不在函数fct中将列表c声明为全局的情况下,它还能工作?变量a的情况并非如此 def fct(): global a # have to declare this for "a" to work, but not for c[] print(a,c) # by not declaring "a" as global, caused this to flag # "accessing a without
def fct():
global a # have to declare this for "a" to work, but not for c[]
print(a,c) # by not declaring "a" as global, caused this to flag
# "accessing a without assignment", which I understand why,
# but why c[] needn't declaration
c[1]=5
a=234
c=[0,0]
a=11
fct()
如果您使用word
global
,这意味着您可以对全局变量进行写入,但如果您只想读取它,则不需要使用global
您不需要在函数体中声明
c
和a
,因为您刚刚在执行fct()
之前声明了它们。好的,这个问题可能需要稍微解释一下
声明:
在大多数支持嵌套作用域的语言中,代码可以引用或重新绑定(分配)最近封闭作用域中的任何名称。目前,Python代码可以引用任何封闭作用域中的名称,但它只能在两个作用域中重新绑定名称:局部作用域(通过简单赋值)或模块全局作用域(使用全局声明)
这里有两件事你必须明白:
- 绑定:创建一个名称,绑定一个值。
例如:
创建一个变量a并为其赋值10>a=10
- 重新绑定:更改绑定到名称的值。
例如:
将值10绑定,然后将5重新绑定到“a”本身>a=10;a=5
def func():
a=5
print(a)
a=10
print("a in the program")
print(a)
print("a in func()")
func()
输出:
a in the program
10
a in func()
5
def func():
global a
print(a)
a=5
print(a)
a=10
print("a in the program")
print(a)
print("a in func()")
func()
现在从func()
中删除a=5
,您将得到:
a in the program
10
a in func()
10
所发生的是a
被发现是10
,并被打印出来
现在,请执行以下操作:
def func():
print(a)
a=5
a=10
print("a in the program")
print(a)
print("a in func()")
func()
你得到这个:
UnboundLocalError: local variable 'a' referenced before assignment
如果在函数中给定a=5
,会发生什么情况
现在不再进行重新绑定,而是创建一个新的局部变量a=5
所以
- 如果在
语句之后/之前没有写入print
,默认情况下,它只打印全局变量a=5
a
- 但是,如果在打印(a)之前写入
,它将创建一个局部变量a=5
,然后将值a
绑定到它(注意:不重新绑定,而是绑定)5
- 但是如果在
之后写入print(a)
,就会弄不清楚为什么要引用尚未创建的变量(局部变量a)a=5
global a
,则打印(a)会愉快地将全局a
打印为10
,然后通过将5绑定到a来创建一个新的局部变量a=5
global a
print(a)
a=5
print(a)
输出:
a in the program
10
a in func()
5
def func():
global a
print(a)
a=5
print(a)
a=10
print("a in the program")
print(a)
print("a in func()")
func()
但其他对象(如list
、dict
等)并非如此。
在本例中,您只是修改一个现有的全局对象,该对象是通过常规名称查找找到的(更改列表条目就像调用列表上的成员函数,而不是名称重新绑定)
因此,它工作正常,没有任何错误。希望您能理解。您没有分配到
c
。通过告诉它为给定索引设置值,您正在变异c
。换句话说,c[…]=…
与c=…
有很大的不同。简单的回答是因为列表是可变的,整数是不可变的。@Anup没有抓住要点。正如Martijn所说,这是因为你只是在改变列表。但即使它是可变的,如果你做了c=…
,你也需要global c
。这就解释了为什么需要global a
;但是OP询问为什么不需要global c
。感谢您指出了绑定列表中“c”的更精细之处,而不是更改其成员之一。