我正在尝试理解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()中明确定义了变量。
答案 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
添加到其非本地范围。