函数命名空间概念(在赋值之前引用)

时间:2017-10-05 08:21:30

标签: python python-2.7 function namespaces local-variables

我在函数中查找了Namespace概念的一些解释。

这是一个代码,它将引发 UnboundLocalError:局部变量...在分配之前引用

x = 1
def foo():
    print x
    x = 2

我明白这应该引发异常。但我想了解python如何知道变量是在本地命名空间中。在行打印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之前,本地命名空间dict为空{}(非常明显)。那么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。 但我正在寻找蟒蛇工作的背后。

1 个答案:

答案 0 :(得分:1)

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

  • 如果它被明确声明为global,则它是全局的(简单情况)。
  • 如果在函数中为 where 分配了一个值而未明确声明global,则它是本地的。
  • 如果仅在函数中读取它,则假定它是全局的(隐式)。

这是在编译时完成的,因此没有执行任何操作来确定这一点。

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

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