2017-10-05 124 views
1

我在函数中使用名称空间概念寻找一些解释。函数名称空间的概念(在赋值之前引用)

下面是这将提高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后面工作。

回答

1

Python将您的代码预编译为一些字节码。在这一步中,它将查找每个范围(通常是函数)标识符是引用全局变量还是局部变量。

  • 如果明确声明为global,则它是全局的(简单的情况)。
  • 如果一个值被赋值给它任何地方在函数中没有被明确地声明为global,它是本地的。
  • 如果仅在函数中读取,则假定为全局(隐式)。

这是在编译时完成的,所以没有执行任何操作来确定它。

现在,在运行时,如果您在分配它之前读取了局部变量,则会出现错误。

现在,类有不同的情况,因为这些变量并不是真正的本地(即位于调用堆栈的内存中)。如果您在b的声明中访问访问a,您将访问模块全局变量,除非存在覆盖模块全局变量的类全局变量。如果您将指定为a,您将创建(或更改)全局类变量。任何后续访问a(或分配给)将访问全局类(或分配给)。

+0

是的,我完全同意你的看法。但是当我在打印这个变量之前打印locals()时,它会给出空字典。那么python如果不在当地人中寻找局部变量,那么哪里呢? –

+0

我不明白。如果您在任何地方的函数中都有一个赋值,那么每个访问和赋值都将被编译为访问局部变量。如果在运行时发生分配,字典将相应地扩展。如果在分配前完成访问,字典将缺少条目,这将引发异常。 – Alfe

+0

我想知道,如果该变量在函数中具有赋值,python将查找某处。因为我知道python首先查看'locals()'内部以检查该变量是否位于本地命名空间中,而globals()则是全局命名空间。所以在哪个变量python中寻找这种情况。 –

相关问题