def Test(value):
def innerFunc():
print value
innerFunc()
def TestWithAssignment(value):
def innerFunc():
print value
value = "Changed value"
innerFunc()
Test("Hello 1")
# Prints "Hello 1"
TestWithAssignment("Hello 2")
# Throws UnboundLocalError: local variable 'value' referenced before assignment
# on the "print value" line
Run Code Online (Sandbox Code Playgroud)
为什么第二个失败,因为唯一的区别是在print语句之后的赋值?我对此非常困惑.
问题是Python希望你是明确的,你想要隐含.Python使用的执行模型将名称绑定到最近的可用封闭范围.
def Test(value):
# Local Scope #1
def innerFunc():
# Local Scope #2
print value
# No immediate local in Local Scope #2 - check up the chain
# First find value in outer function scope (Local Scope #1).
# Use that.
innerFunc()
def TestWithAssignment(value):
# Local Scope #1
def innerFunc():
# Local Scope #2
print value
# Immediate local variable found in Local Scope #2.
# No need to check up the chain.
# However, no value has been assigned to this variable yet.
# Throw an error.
value = "Changed value"
innerFunc()
Run Code Online (Sandbox Code Playgroud)
没有(据我所知)走了在Python 2.x的范围的方式-你必须globals()和locals()-但全球和局部范围之间的任何范围不能被访问(如果这是不正确的,我会喜欢被纠正).
但是,您可以将局部变量传递value到内部本地范围:
def TestWithAssignment(value):
def innerFunc(value):
print value
# Immediate local **and assigned now**.
value = "Changed value"
# If you need to keep the changed value
# return value
innerFunc(value)
# If you need to keep the changed value use:
# value = innerFunc(value)
Run Code Online (Sandbox Code Playgroud)
在Python 3中,您可以使用新nonlocal语句来引用包含范围(Thanks @Thomas K).
def TestWithAssignment(value):
def innerFunc():
nonlocal value
print value
value = "Changed value"
innerFunc()
Run Code Online (Sandbox Code Playgroud)