do_local中定义的变量生成错误:变量...在声明之前被引用

时间:2018-02-01 12:47:05

标签: python class object namespaces

我正在尝试理解Python中的命名空间。

我尝试了Python文档中给出的这种情况。

def scope_test():
    def do_local():
        spam = "local spam"
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"
    def do_global():
        global spam
        spam = "global spam"
    do_local()
    print("before local assignment:", spam)
    do_nonlocal()
    print("before nonlocal assignment:", spam)
    do_global()
    print("before global assignment:", spam)

    spam = "test spam"

    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

这说不清楚:

  

变量垃圾邮件在声明之前被引用。

我已经在do_local()中明确定义了变量。

1 个答案:

答案 0 :(得分:0)

我从一个简单的例子开始:我尝试访问一个尚未在任何地方定义的非局部变量。这将失败:

def scope_test1():

    # This function tries to access a non-local
    # variable spam. Since I never define spam,
    # this will cause an exception:
    # -> SyntaxError: no binding for nonlocal 'spam' found
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

这很容易解决:我只需要在适当的范围内添加此变量:

def scope_test2():

    # This works:
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

    spam = "test spam"

现在我想添加我的函数的本地版本,以使事情变得更有趣:

def scope_test3():

    # This function defines the variable spam, but
    # only locally, that is, it is not accesible from
    # outside
    def do_local():
        spam = "local spam"

    # The functions do_local() gets executed and
    # creates an internal variable spam. This variable
    # isn’t visible from the outside.
    do_local()

    # So far, the variable spam hasn’t been declared.
    # So this will fail:
    # -> UnboundLocalError: local variable 'spam' referenced before assignment
    print("after local assignment:", spam)

    # spam gets assigned here, but it’s too late
    spam = "test spam"

它再次失败:我稍后定义spam没有帮助(这太晚了),并且do_local在本地分配给spam也无济于事:函数scope_test3看不到此本地版本。

我可能会尝试通过添加非本地版本来补救这种情况:

def scope_test4():

    def do_local():
        spam = "local spam"

    # Accesses a nonlocal variable spam when it gets called,
    # but doesn't add it, so it can’t save us.
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

    do_local()

    # So far, the variable spam still hasn’t been declared.
    # So this will still fail:
    # -> UnboundLocalError: local variable 'spam' referenced before assignment
    print("after local assignment:", spam)

    # spam gets assigned here, but it’s still too late
    spam = "test spam"

但这也无济于事:do_nonlocal不会仅仅通过现有神奇地将spam添加到其非本地范围。