从父函数传递参数到嵌套函数 Python
这是我的代码:
def f(x):
def g(n):
if n < 10:
x = x + 1
g(n + 1)
g(0)
当我计算 f(0) 的时候,会出现一个错误:“x 在赋值之前被引用”。
但是,当我用“print x”替代“x = x + 1”时,它就能正常工作。
看起来在 g 的范围内,我只能把 x 当作“使用”的情况,而不能当作“绑定”的情况。我猜问题在于 f 只把 x 的值传给了 g。
我这样理解对吗?如果不对,能有人解释一下为什么“x = x + 1”的左边在引用之前没有定义吗?
谢谢
2 个回答
1
是的,给变量命名和读取它们的值是两回事。在一个函数里,如果你给某个名字赋值,那这个名字就被认为是这个函数的局部变量,除非你特别说明。
在Python 2中,唯一的“特别说明”方法是使用global
语句,这样你就可以给全局变量赋值。在Python 3中,你还可以使用nonlocal
语句来给一个更高层级(但不一定是全局的)作用域里的变量赋值。
在你的例子中,x
是在一个更高层级但不是全局的作用域(就是函数f
)。所以在Python 2中,你无法在g
函数里给x
赋值。而在Python 3中,你可以在g
里用nonlocal x
语句来做到这一点。
7
你理解得没错。在Python 2中,你不能在嵌套的作用域中使用x
来进行赋值。
在Python 3中,你可以通过把变量标记为nonlocal
来继续使用它进行绑定;这个关键词就是为了这个用途而引入的:
def f(x):
def g(n):
nonlocal x
if n < 10:
x = x + 1
g(n + 1)
g(0)
在Python 2中,你有一些变通的方法;可以使用可变对象来避免需要绑定,或者(滥用)函数属性:
def f(x):
x = [x] # lists are mutable
def g(n):
if n < 10:
x[0] = x[0] + 1 # not assigning, but mutating (x.__setitem__(0, newvalue))
g(n + 1)
g(0)
或者
def f(x):
def g(n):
if n < 10:
g.x = g.x + 1
g(n + 1)
g.x = x # attribute on the function!
g(0)