Rug*_*rra 9 python recursion closures scope
为什么这样做:
def function1():
a = 10
def function2():
print a
function2()
Run Code Online (Sandbox Code Playgroud)
但这不是:
def function1():
a = 10
def function2():
print a
a -= 1
if a>0:
function2()
function2()
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
UnboundLocalError: local variable 'a' referenced before assignment
Run Code Online (Sandbox Code Playgroud)
cha*_*ieb 14
该错误似乎不是对根本问题的描述.迈克解释了这些消息,但这并没有解释根本原因.
实际问题是在python中你不能分配给已关闭的变量.所以在function2中'a'是只读的.当你分配给它时,你创建一个新的变量,正如迈克指出的那样,你在写之前就读过了.
如果你想从内部范围分配到外部变量,你必须像这样作弊:
def function1():
al = [10]
def function2():
print al[0]
al[0] -= 1
if al[0]>0:
function2()
function2()
Run Code Online (Sandbox Code Playgroud)
所以al是不可变的,但它的内容不是,你可以在不创建新变量的情况下更改它们.
应该注意,这是Python中的语法故障.Python本身(在字节码级别)可以很好地分配给这些变量; 在2.x中根本没有语法表示你想要这样做.它假定如果您在嵌套级别中分配变量,则意味着它是它的本地变量.
这是一个巨大的缺点; 能够分配到闭包是至关重要的.我曾多次与charlieb的黑客一起解决这个问题.
Python 3使用非常笨拙的"非本地"关键字修复了这个问题:
def function1():
a = 10
def function2():
nonlocal a
print(a)
a -= 1
if a>0:
function2()
function2()
function1()
Run Code Online (Sandbox Code Playgroud)
这种语法仅在3.x中可用,这是非常差的; 大多数人都陷入2.x,并且必须继续使用黑客来解决这个问题.这非常需要向后移植到2.x.
http://www.python.org/dev/peps/pep-3104/