函数名称空间的概念(在赋值之前引用)
问题描述:
我在函数中使用名称空间概念寻找一些解释。函数名称空间的概念(在赋值之前引用)
下面是这将提高UnboundLocalError代码:局部变量赋值...
x = 1
def foo():
print x
x = 2
之前引用我明白了这一点应该引发异常。但我想了解python知道变量是如何在本地命名空间中的。在行print x处,x不在局部变量dict中。
x = 1
def foo():
print 'local before print x : ',locals()
print x
print 'local after print x :',locals()
x = 2
foo() # call function, print local namespace before raising exception
local before print x : {}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in foo
UnboundLocalError: local variable 'x' referenced before assignment
在打印x之前,本地命名空间字典是空{}(这是非常明显的)。那么python如何知道x是局部变量。
这与类
a = [1]
class b():
c = a
a = 2
print 'c inside class ', b.c
'c inside class [1]'
d = b()
不发生异常,在类类似案件的工作方式不同。
如果有人可以帮助我解释概念,python在赋值之前如何知道这个变量是局部变量。
我查了很多表单和网站的解释,但没有找到任何。
有帖子和形式解释如何解决这种情况。例。 UnboundLocalError: local variable … referenced before assignment。 但我正在寻找Python后面工作。
答
Python将您的代码预编译为一些字节码。在这一步中,它将查找每个范围(通常是函数)标识符是引用全局变量还是局部变量。
- 如果明确声明为
global
,则它是全局的(简单的情况)。 - 如果一个值被赋值给它任何地方在函数中没有被明确地声明为
global
,它是本地的。 - 如果仅在函数中读取,则假定为全局(隐式)。
这是在编译时完成的,所以没有执行任何操作来确定它。
现在,在运行时,如果您在分配它之前读取了局部变量,则会出现错误。
现在,类有不同的情况,因为这些变量并不是真正的本地(即位于调用堆栈的内存中)。如果您在b
的声明中访问访问a
,您将访问模块全局变量,除非存在覆盖模块全局变量的类全局变量。如果您将指定为至a
,您将创建(或更改)全局类变量。任何后续访问a
(或分配给)将访问全局类(或分配给)。
是的,我完全同意你的看法。但是当我在打印这个变量之前打印locals()时,它会给出空字典。那么python如果不在当地人中寻找局部变量,那么哪里呢? –
我不明白。如果您在任何地方的函数中都有一个赋值,那么每个访问和赋值都将被编译为访问局部变量。如果在运行时发生分配,字典将相应地扩展。如果在分配前完成访问,字典将缺少条目,这将引发异常。 – Alfe
我想知道,如果该变量在函数中具有赋值,python将查找某处。因为我知道python首先查看'locals()'内部以检查该变量是否位于本地命名空间中,而globals()则是全局命名空间。所以在哪个变量python中寻找这种情况。 –