Python变量解析
给定以下代码:Python变量解析,python,Python,给定以下代码: a = 0 def foo(): # global a a += 1 foo() 运行时,Python会抱怨:UnboundLocalError:在赋值之前引用了局部变量“a” 然而,当它是一本字典 a = {} def foo(): a['bar'] = 0 foo() 事情进展得很顺利 有人知道为什么我们可以在第二段代码中引用a,而不是第一段吗?问题是更新 无法更新a,因为它不是函数本地命名空间中的变量。就地更新分配操作无法就地更新a 有趣的是,a=a+1也失
a = 0
def foo():
# global a
a += 1
foo()
运行时,Python会抱怨:UnboundLocalError:在赋值之前引用了局部变量“a”
然而,当它是一本字典
a = {}
def foo():
a['bar'] = 0
foo()
事情进展得很顺利
有人知道为什么我们可以在第二段代码中引用a,而不是第一段吗?问题是更新 无法更新
a
,因为它不是函数本地命名空间中的变量。就地更新分配操作无法就地更新a
有趣的是,a=a+1
也失败了
Python为这类语句生成稍微优化的代码。它使用“LOAD_FAST”指令
2 0 LOAD_FAST 0 (a)
3 LOAD_CONST 1 (1)
6 INPLACE_ADD
7 STORE_FAST 0 (a)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
请注意,在等号的左侧和右侧使用a
会导致这种优化
但是,您可以访问a
,因为Python将为您搜索本地和全局名称空间
由于a
不会出现在赋值语句的左侧,因此使用了不同类型的访问,“LOAD\u GLOBAL”
不同之处在于,在第一个示例中,您分配给
a
,它创建了一个新的本地名称a
,该名称隐藏了全局a
在第二个示例中,您没有向a
赋值,因此使用全局a
这在本手册中有介绍
Python的一个特殊怪癖是——如果没有有效的全局语句——对名称的赋值总是进入最内部的范围
a+=1
相当于a=a+1
。通过分配给变量a
,使其成为本地变量。您尝试分配a+1
的值失败,因为a
尚未绑定。这是一个非常常见的Python问题:如果您分配给函数中的变量(就像您分配给函数中的变量一样,+=
),则它不会使用全局变量。但是,由于您所做的实际上是“a=a+1”,因此在分配给它之前,您尝试访问a
(在表达式的右侧)
尝试在函数开头使用global a
(但要注意,这样会覆盖globala
值)
在第二个示例中,您没有为变量
a
赋值,而是只给它的一个项赋值。所以使用了全局dicta
。我想知道为什么他们决定将其描述为“特殊怪癖”?与javascript相比,a=1
自动分配给全局范围!唯一的好处是,您可以通过不使用var a=1
2 0 LOAD_CONST 1 (0)
3 LOAD_GLOBAL 0 (a)
6 LOAD_CONST 2 ('bar')
9 STORE_SUBSCR
10 LOAD_CONST 0 (None)
13 RETURN_VALUE