有这段代码:
def f():
x = m
m = 2
def g():
x = m
f() # UnboundLocalError: local variable 'm' referenced before assignment
g() # NameError: global name 'm' is not defined
在两个函数体中都使用了变量m
,它在使用时未定义,但错误消息不同。 Python在使用它们之前是否知道函数中定义了哪些变量(如函数f
)?为什么错误消息不同?
答案 0 :(得分:2)
如果函数中的任何位置都有赋值,那么它在该函数中的任何位置都被视为局部变量。这意味着对于函数f()
,即使在尝试访问m
后发生m
的分配,行[{1}}也只会查找名称{{1}在本地范围内。这就是x = m
的错误消息将m
称为局部变量的原因。
在函数f()
中没有m
的分配,因此行g()
将使用here描述的顺序查找m
:
x = m
的错误消息,“全局名称'm'未定义”,指的是全局范围,因为这是搜索的最后一个位置(内置除外,但它会让人感到困惑)有一条消息,如“在内置命名空间中找不到名称'm'。”。
答案 1 :(得分:1)
Python一旦调用它就会检查它。
导入时,直接在解释器中输入时,只关注是否违反了任何语法规则。它并不关心这个级别的本地人或全局。
>>> def foo():
... print locals()
... bar = 34
... print locals()
... DIP = SET
...
>>>
>>> foo()
{}
{'bar': 34}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in foo
NameError: global name 'SET' is not defined
它从上到下运行,并检查locals()和globals(),如果它看到该变量然后它就可以了,并对它做任何事情。
它甚至适用于定义和子定义......或者您要分配的任何其他内容
>>> def foo():
... bar()
... def bar():
... print("never gonna give you up")
...
>>>
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in foo
UnboundLocalError: local variable 'bar' referenced before assignment
答案 2 :(得分:0)
是。如果在函数中的任何位置分配变量(不使用global
关键字),Python会将函数中对该名称的所有引用视为本地。
答案 3 :(得分:0)
执行函数时,实际上是在函数对象上调用__call()__
。
解析脚本时,在脚本全局命名空间中创建函数对象。 创建但未执行。
作为解析过程的一部分,计算对象名称空间。因此,解释器实际上可以知道哪个变量存在以及何时存在。
答案 4 :(得分:0)
def f():
x = m
m = 2
当解析上面的函数时,python认为m
是找到m = 2
的局部变量,所以当实际调用该函数时x = m
会引发错误,因为m
是尚未在当地范围内定义。
def g():
x = m
在这个python中认为m
将来自全局范围的某个值,它首先搜索全局命名空间然后搜索内置命令,但是当在任何地方找不到m
时,错误是提高。
>>> m = 1
>>> def g():
x = m
>>> g() #works fine because `m` is found in global scope
>>> def g():
x = sum
>>> g() # sum is found in built-ins
要修改全局变量,请使用global
:
>>> m = 1
>>> def g():
global m
m += 1
...
>>> g()
>>> m
2
答案 5 :(得分:0)
您需要在函数
中使用global m