关于Python:unboundlocalerror scopes嵌套的功能。

UnboundLocalError with nested function scopes

我有这样的代码(简化):

1
2
3
4
5
6
7
def outer():
    ctr = 0

    def inner():
        ctr += 1

    inner()

ctr会导致错误:

1
2
3
4
5
6
7
8
Traceback (most recent call last):
  File"foo.py", line 9, in <module>
    outer()
  File"foo.py", line 7, in outer
    inner()
  File"foo.py", line 5, in inner
    ctr += 1
UnboundLocalError: local variable 'ctr' referenced before assignment

我怎么修这个?我以为嵌套的作用域会允许我这样做。我试过用"全球",但还是不行。


如果你使用Python 3、你可以使用nonlocal语句重新绑定到非局部名字:enable of a

1
2
3
4
5
6
7
8
def outer():
    ctr = 0

    def inner():
        nonlocal ctr
        ctr += 1

    inner()

如果你使用Python 2,但没有nonlocal,你需要将你的incrementing没有重新绑定(由barename保鲜柜台作为一个项目或属性的一些barename,不是一barename本身)。例如:

1
2
3
4
5
6
...
ctr = [0]

def inner():
    ctr[0] += 1
...

和课程使用ctr[0]无论你现在使用的ctr裸露的地方。


从http:/ / / / / C www.devshed.com /嵌套函数在Python Python / 1 /

Code in a nested function's body may
access (but not rebind) local
variables of an outer function, also
known as free variables of the nested
function.

所以,你将需要一个明确的ctrinner护照。


的解释

每当一个变量分配一个值给变量a的Python函数,认为这是一个本地变量的函数。从一个包含赋值语句ctr += 1ctr认为,Python的innerctr是局部的功能。因此,即使它不看商务价值的ctr变量被定义在outer'。本:什么是基本的Python湖

1
2
def inner():
    ctr = ctr + 1

我认为我们可以同意,因为这是所有的代码没有错误,因为它是我们的ctr访问之前,已被定义。

(参见本问题的更多细节关于Python的知识范围决定的变量。)

的解决方案(在Python 3)

3《nonlocal安切洛蒂介绍Python语句,这样的作品多为美国global语句,但访问变量的函数(而不是全局变量比周边)。简单的添加nonlocal ctr在顶innerfunction和问题:想走开

1
2
3
4
5
6
7
8
def outer():
    ctr = 0

    def inner():
        nonlocal ctr
        ctr += 1

    inner()

在工作区(在Python 2)

nonlocalPython声明不存在2,我们有一个crafty。有两个简单的解决方法:

  • 删除所有分配到ctr

    因为Python ctr只考虑本地变量,因为它是在一个变量赋值的问题,如果我们想离开删除所有作业ctr友好的名称。但我们怎么能改变变量的值分配给它的没有?易:我们的变量a mutable包对象,像一个列表。然后我们可以修改列表都是没有价值的ctr分配A名称:

    1
    2
    3
    4
    5
    6
    7
    def outer():
        ctr = [0]

        def inner():
            ctr[0] += 1

        inner()
  • 作为一个参数传递到innerctr

    1
    2
    3
    4
    5
    6
    7
    8
    def outer():
        ctr = 0

        def inner(ctr):
            ctr += 1
            return ctr

        ctr = inner(ctr)

如何declaring ctrouter(IU在全球范围),或任何其他类的函数?这将使writable和变量的访问。