代码之家  ›  专栏  ›  技术社区  ›  Matt Joiner

python中的本地函数

  •  33
  • Matt Joiner  · 技术社区  · 15 年前

    在下面的python代码中,我得到一个 UnboundLocalError .据我所知,局部函数共享包含函数的局部变量,但这在这里似乎很难实现。我认识到 a 在此上下文中是不可变的值,但这不应该是问题。

    def outer():
        a = 0
        def inner():
            a += 1
        inner()
    outer()
    

    似乎内部函数已经收到了父函数中所有引用的副本,因为我没有得到 未绑定本地错误 如果的值为 包装为可变类型。

    是否有人能够澄清这里的行为,并向我指出相关的Python文档?

    3 回复  |  直到 15 年前
        1
  •  31
  •   Joshua Taylor    9 年前

    我相信你认为这是一个“可变性”的问题是正确的。虽然您发布的代码不会引发“UnboundLocalError”,但以下代码不会:

    def outer():
        a = 0
        def inner():
            print a
        inner()
    outer()
    

    Python不允许您从内部作用域的外部作用域重新分配变量的值(除非您使用关键字“global”,这在本例中不适用)。

    查看此python 2.6.2文档中“classes”文档的底部部分:

    9.2. Python Scopes and Namespaces

    […]如果名称声明为全局名称,则所有引用和分配都将转到 直接到包含模块全局名称的中间作用域。 否则,在最内部范围之外找到的所有变量都是 只读(尝试写入此类变量只会创建一个 最内部范围中的新局部变量,使 命名的外部变量不变)。

    您的“unboundLocalError”是因为您的函数实际上声明了一个名为“a”的新变量,然后立即尝试对其执行“+=”操作,但由于“a”还没有值,所以失败了。(将“a+=1”视为“a=a+1”,如果“a”未定义,则可以看到问题)。

    一般来说,如果你想修改“a”,人们通常绕过它的方式是使用可变类型传递“a”(如列表或字典)。您可以通过可变类型的内容修改“A”(正如您在使用此设置进行测试时可能注意到的那样)。

    希望有帮助!

        2
  •  10
  •   Unknown    15 年前

    尝试将变量绑定为参数。

    def outer():
        a = 0
        def inner(a=a):
            a += 1
    
        inner()
    
    outer()
    

    我会设法找出适当的文件。

    编辑

    因为您希望内部函数对外部作用域有副作用,所以需要使用一个可变的数据类型,如列表。整数和字符串是不可变的。

    def outer():
        a = [0]
        def inner():
            a[0] += 1
        inner()
        print a[0]
    outer()
    
        3
  •  8
  •   vaduha    12 年前

    您应该将变量指定为非局部变量以在闭包中保留其状态,因此定义应该如下所示

    def outer():
    a = 0
    def inner():
        nonlocal a
        a += 1
    inner()