好吧,我只是试着看看变量范围如何工作并在以下情况下运行.全部从终端跑:
x = 1
def inc():
x += 5
inc()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in inc
UnboundLocalError: local variable 'x' referenced before assignment
Run Code Online (Sandbox Code Playgroud)
所以我思考得很好也许我的方法无法访问x,所以我尝试了:
def inc():
print(x)
1
Run Code Online (Sandbox Code Playgroud)
这样可行.现在我知道我可以这样做:
def inc():
global x
x += 1
Run Code Online (Sandbox Code Playgroud)
这会奏效.但我的问题是为什么第一个例子失败了.我的意思是我希望自从print(x)
工作以来x在函数内可见,那么为什么x + = 5失败?
Lou*_*uis 38
不同于采用"真实"词法范围的语言,Python的选择让特定的"命名空间"变量,无论是global
,nonlocal
或本地.可以说,让开发人员有意识地编写这样的命名空间代码更加明确,因此更容易理解.我认为这种复杂性使得语言更加笨拙,但我想这完全归功于个人偏好.
以下是一些例子global
: -
>>> global_var = 5
>>> def fn():
... print(global_var)
...
>>> fn()
5
>>> def fn_2():
... global_var += 2
... print(global_var)
...
>>> fn_2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fn_2
UnboundLocalError: local variable 'global_var' referenced before assignment
>>> def fn_3():
... global global_var
... global_var += 2
... print(global_var)
...
>>> fn_3()
7
Run Code Online (Sandbox Code Playgroud)
相同的模式也可以应用于nonlocal
变量,但此关键字仅适用于后面的Python版本.
如果您想知道,nonlocal
在变量不是全局变量但不在函数定义范围内的情况下使用它.例如,a def
中的a def
,这是一种常见的情况,部分原因是缺少多语句lambdas.虽然在早期的Pythons中有一个黑客可以绕过这个功能的缺乏,我依旧记得它涉及使用单个元素列表......
请注意,写入变量是需要这些关键字的地方.只是阅读它们并不含糊,因此不需要.除非你的内部def
使用与外部变量名称相同的变量名称,否则应该避免诚实.
unu*_*tbu 21
当Python解析一个函数时,它会记录何时进行变量赋值.当存在赋值时,它默认假定该变量是局部变量.要声明赋值引用全局变量,必须使用global
声明.
当您访问函数中的变量时,将使用LEGB作用域规则查找其值.
所以,第一个例子
x = 1
def inc():
x += 5
inc()
Run Code Online (Sandbox Code Playgroud)
产生一个UnboundLocalError
因为Python确定x
内部inc
是一个局部变量,
x
在第二个例子中访问工作时
def inc():
print x
Run Code Online (Sandbox Code Playgroud)
因为在这里,根据LEGB规则,Python x
在本地范围内查找,找不到它,然后在扩展范围内查找它,仍然找不到它,最后在全局范围内成功查找它.
定义函数时决定函数的本地名称:
>>> x = 1
>>> def inc():
... x += 5
...
>>> inc.__code__.co_varnames
('x',)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,x
存在于本地名称空间中.执行x += 5
需要预先存在的值x
(对于整数,它就像x = x + 5
),并且这在函数调用时失败,因为本地名称是未绑定的 - 这正是异常UnboundLocalError
被命名的原因.
比较其他版本,其中x
不是局部变量,因此可以在全局范围内解析:
>>> def incg():
... print(x)
...
>>> incg.__code__.co_varnames
()
Run Code Online (Sandbox Code Playgroud)
常见问题中的类似问题:http: //docs.python.org/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
归档时间: |
|
查看次数: |
80812 次 |
最近记录: |