【问题标题】:Variable defined in do_local generates error: The variable ... is referenced before it is declareddo_local 中定义的变量生成错误:变量 ... 在声明之前被引用
【发布时间】:2018-07-11 19:13:32
【问题描述】:

我正在尝试理解 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)

这失败了:

变量 spam 在声明之前被引用。

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

【问题讨论】:

  • do_local 定义了一个局部变量。它不存在于do_local 的范围之外。
  • 是的,你定义了它,它说是本地的,所以这个变量只在do_local()的范围内可见

标签: python class object namespaces


【解决方案1】:

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

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 添加到它的非本地范围内。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多