来自Google样式指南的词法范围:
嵌套的Python函数可以引用封闭函数中定义的变量,但不能赋值给它们.
这两个似乎最初都要检查:
# Reference
def toplevel():
a = 5
def nested():
print(a + 2)
nested()
return a
toplevel()
7
Out[]: 5
# Assignment
def toplevel():
a = 5
def nested():
a = 7 # a is still 5, can't modify enclosing scope variable
nested()
return a
toplevel()
Out[]: 5
Run Code Online (Sandbox Code Playgroud)
那么,为什么嵌套函数中的引用和赋值的组合会导致异常呢?
# Reference and assignment
def toplevel():
a = 5
def nested():
print(a + 2)
a = 7
nested()
return a
toplevel()
# UnboundLocalError: local variable 'a' referenced before assignment
Run Code Online (Sandbox Code Playgroud)
Moh*_*ohd 11
在第一种情况下,您指的是一个nonlocal好的变量,因为没有调用局部变量a.
def toplevel():
a = 5
def nested():
print(a + 2) # theres no local variable a so it prints the nonlocal one
nested()
return a
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,您创建一个本地变量a也很好(本地a将与非本地变量不同,这就是为什么原始a未被更改).
def toplevel():
a = 5
def nested():
a = 7 # create a local variable called a which is different than the nonlocal one
print(a) # prints 7
nested()
print(a) # prints 5
return a
Run Code Online (Sandbox Code Playgroud)
在第三种情况下,您创建一个局部变量,但print(a+2)在此之前就已经存在,这就是引发异常的原因.因为print(a+2)将引用a在该行之后创建的局部变量.
def toplevel():
a = 5
def nested():
print(a + 2) # tries to print local variable a but its created after this line so exception is raised
a = 7
nested()
return a
toplevel()
Run Code Online (Sandbox Code Playgroud)
要实现您想要的,您需要nonlocal a在内部函数内部使用:
def toplevel():
a = 5
def nested():
nonlocal a
print(a + 2)
a = 7
nested()
return a
Run Code Online (Sandbox Code Playgroud)
Bra*_*mon 11
对于任何遇到此问题的人,除了此处接受的答案外,Python 文档中还对其进行了简明回答:
这段代码:
Run Code Online (Sandbox Code Playgroud)>>> x = 10 >>> def bar(): ... print(x) >>> bar() 10有效,但这段代码:
Run Code Online (Sandbox Code Playgroud)>>> x = 10 >>> def foo(): ... print(x) ... x += 1结果是
UnboundLocalError.这是因为当您对作用域中的变量进行赋值时,该变量将成为该作用域的局部变量,并隐藏外部作用域中任何类似命名的变量。由于 foo 中的最后一条语句为 分配了一个新值
x,编译器将其识别为局部变量。因此,当之前print(x)尝试打印未初始化的局部变量时会导致错误。在上面的示例中,您可以通过声明来访问外部作用域变量
global:Run Code Online (Sandbox Code Playgroud)>>> x = 10 >>> def foobar(): ... global x ... print(x) ... x += 1 >>> foobar() 10您可以使用
nonlocal关键字在嵌套范围内执行类似的操作:Run Code Online (Sandbox Code Playgroud)>>> def foo(): ... x = 10 ... def bar(): ... nonlocal x ... print(x) ... x += 1 ... bar() ... print(x) >>> foo() 10 11
| 归档时间: |
|
| 查看次数: |
3606 次 |
| 最近记录: |