5

在 Python 2.7 中,运行以下代码:

def f():
    a = a + 1

f()

给出以下结果:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    f()
  File "test.py", line 2, in f
    a = a + 1
UnboundLocalError: local variable 'a' referenced before assignment

但是,如果我将代码更改为以下内容:

def f():
    a[0] = a[0] + 1

f()

我得到不同的错误:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    f()
  File "test.py", line 2, in f
    a[0] = a[0] + 1
NameError: global name 'a' is not defined

为什么当 Python是一个全局a变量时,它是一个局部变量?这背后的原因是什么?intlist

PS:我在阅读这个帖子后正在尝试。

4

2 回答 2

7

密钥可在赋值语句的文档中找到:

将对象分配给单个目标的递归定义如下。

如果目标是标识符(名称)(例如a = a + 1

  • 如果名称没有出现在当前代码块中的全局语句中:名称绑定到当前本地命名空间中的对象。
  • 否则:名称绑定到当前全局命名空间中的对象。

如果名称已经绑定,则为反弹。这可能会导致先前绑定到名称的对象的引用计数达到零,从而导致对象被释放并调用其析构函数(如果有的话)。

...

如果目标是订阅(例如a[0] = a[0] + 1:评估引用中的主要表达式。它应该产生一个可变序列对象(例如列表)或映射对象(例如字典)。接下来,计算下标表达式。

f1 Python 中看到您正在将某个值绑定到a,看到a尚未global a在此范围内的语句中使用并准备一个局部变量。然后它尝试计算表达式a + 1,查找变量a并找到一个未初始化的局部变量。这导致UnboundLocalError.

f2 Python 中,您正在为变量的订阅分配一些值a。它在本地命名空间中查找该变量,但找不到它。然后它沿着非本地命名空间(闭包)向上走,直到到达全局命名空间。一旦a在全局命名空间中找不到它,它就会抛出一个NameError.

于 2013-03-24T03:33:46.353 回答
-1

你能尝试做这样的事情吗:

def f(a):
    a += 1
    print a

def g():
    a = 3
    f(a)

g()
于 2013-03-24T03:33:35.873 回答