Python全局变量和局部变量

Fis*_*tor 5 python scope global-variables

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

def f():
    a = a + 1

f()
Run Code Online (Sandbox Code Playgroud)

给出以下结果:

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
Run Code Online (Sandbox Code Playgroud)

但是,如果我将代码更改为:

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

f()
Run Code Online (Sandbox Code Playgroud)

我得到了不同的错误:

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
Run Code Online (Sandbox Code Playgroud)

为什么Python考虑a是一个局部变量,当它是一个int全局的时候list?这背后的理由是什么?

PS:我在读完这个帖子后正在做实验.

Sea*_*ira 6

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

如下递归地定义对象到单个目标的分配.

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

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

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

...

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

f1 Python中看到你绑定了一些值a,看到它a没有global a在这个范围的语句中使用并准备一个局部变量.然后它尝试评估表达式a + 1,查找变量a并找到未初始化的局部变量.这导致了UnboundLocalError.

f2 Python中,您会看到您为变量的订阅分配了一些值a.它在本地命名空间中查找该变量并且无法找到它.然后它会遍历非本地命名空间(闭包),直到它到达全局命名空间.一旦它无法a在全局命名空间中找到它就会抛出一个NameError.