-1

有这个代码:

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)?为什么错误信息不同?

4

6 回答 6

2

如果在函数中的任何地方都对变量进行了赋值,那么它在该函数中的任何地方都被认为是局部变量。这意味着对于 function f(),即使m在尝试访问之后分配 to m,该行x = m也只会m在本地范围内查找名称。这就是错误消息f()m称为局部变量的原因。

在函数g()中没有分配到m,因此该行将使用此处描述的顺序x = m查找:m

  • 首先搜索的最内层范围包含本地名称
  • 从最近的封闭范围开始搜索的任何封闭函数的范围包含非本地名称,但也包含非全局名称
  • 倒数第二个范围包含当前模块的全局名称
  • 最外层范围(最后搜索)是包含内置名称的命名空间

“未定义全局名称'm'”的错误消息g()是指全局范围,因为这是搜索的最后一个位置(内置位置除外,但如果出现“名称”之类的消息会令人困惑在内置命名空间中找不到 m'")。

请注意,您可以使用globalornonlocal语句来更改此行为(nonlocal仅存在于 Python 3.x 中)。

于 2013-05-28T16:29:56.277 回答
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
于 2013-05-28T16:40:22.123 回答
0

是的。如果您在函数中的任何位置分配给变量(不使用global关键字),Python 会将函数中对该名称的所有引用视为本地的。

于 2013-05-28T16:27:47.360 回答
0

当你执行一个函数时,你实际上是__call()__在一个函数对象上调用。

解析脚本时,会在脚本全局命名空间中创建函数对象。已创建,但未执行。

作为解析过程的一部分,计算对象名称空间。所以解释器实际上可以知道哪个变量存在以及何时存在。

于 2013-05-28T16:31:05.250 回答
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
于 2013-05-28T16:32:17.910 回答
0

您需要global m在函数内部使用

于 2013-05-28T16:43:23.033 回答