3

我有一个简单的例子:


def func1():
    local_var = None

    def func(args):
        print args,
        print "local_var:", local_var

        local_var = "local"

    func("first")
    func("second")

func1()

我希望输出是:

第一个 local_var:无
第二个 local_var:本地

但是,我的实际输出是:

第一个本地变量:
回溯(最近一次通话最后):
  文件“test.py”,第 13 行,在
    函数1()
  func1 中的文件“test.py”,第 10 行
    函数(“第一个”)
  文件“test.py”,第 6 行,在 func 中
    打印“local_var:”,local_var
UnboundLocalError:分配前引用的局部变量“local_var”

我对 python 范围规则的理解表明这应该按预期工作。我有其他代码可以按预期工作,但是将一个不工作的代码片段减少到上面的微不足道的情况也不起作用。所以我很难过。

4

4 回答 4

9

local_var对in的赋值func使其成为局部变量func因此该print语句在被赋值之前引用了“非常局部”的变量,正如异常所说的那样。正如 jtb 所说,在 Python 3 中,您可以使用 来解决这个问题nonlocal,但从代码中可以清楚地看出,使用print语句,您正在使用 Python 2。Python 2 中的传统解决方案是确保分配不是裸名因此不会使变量比您希望的更局部,例如:

def func1():
    local_var = [None]

    def func(args):
        print args,
        print "local_var:", local_var[0]

        local_var[0] = "local"

    func("first")
    func("second")

func1()

对索引的分配不是裸名,因此不会影响局部性,并且从 Python 2.2 开始,嵌套内部函数引用外部包含函数中的局部变量是完全可以接受的,这就是这个版本所做的一切(分配给barenames 是与引用变量不同的问题)。

于 2009-07-28T17:58:36.537 回答
1

在 Python 3.0 之前,函数无法写入外部范围内的非全局变量。Python3 引入了nonlocal让这个工作的关键字。您将在' 定义nonlocal local_var的顶部添加以获得您期望的输出。func()参见PEP 3104

如果您不在 Python 3 中工作,则必须将变量设为全局变量,或者以某种方式将其传递给函数。

于 2009-07-28T17:47:24.187 回答
1

在 3.0 之前解决这个问题的标准方法是

def func1():
    local_var = [None]

    def func(args):
        print args,
        print "local_var:", local_var[0]

        local_var[0] = "local"

    func("first")
    func("second")

func1()
于 2009-07-28T17:56:25.120 回答
1

Python 的作用域规则在这个相关问题中进行了讨论和解释:

不直观的 UnboundLocalError 行为的原因

于 2009-07-28T17:58:16.070 回答