Python 内部方法无法从外部方法获取变量
Python inner method cannot get variable from outer method
代码如下:
def cycle(f1, f2, f3):
"""Returns a function that is itself a higher-order function.
>>> def add1(x):
... return x + 1
>>> def times2(x):
... return x * 2
>>> def add3(x):
... return x + 3
>>> my_cycle = cycle(add1, times2, add3)
>>> identity = my_cycle(0)
>>> identity(5)
5
>>> add_one_then_double = my_cycle(2)
>>> add_one_then_double(1)
4
>>> do_all_functions = my_cycle(3)
>>> do_all_functions(2)
9
>>> do_more_than_a_cycle = my_cycle(4)
>>> do_more_than_a_cycle(2)
10
>>> do_two_cycles = my_cycle(6)
>>> do_two_cycles(1)
19
"""
"*** YOUR CODE HERE ***"
def execution(n):
def inner(x):
result = x
while (n > 0):
n = n - 1
if (n >= 0):
result = f1(result)
n = n - 1
if (n >= 0):
result = f2(result)
n = n - 1
if (n >= 0):
result = f3(result)
return result
return inner
return execution
运行 在终端测试
$ python -m doctest xx.py
得到错误:
UnboundLocalError: local variable 'n' referenced before assignment
我认为方法inner
中使用的n
变量可以从外部方法execution
中获取,因为在运行时,execution
必须是第一次调用是调用getinner
方法,所以变量n
肯定已经初始化了。我在这里犯了什么错误?我用的是python 3.8.1
发生了什么事,为什么?基于变量范围,您希望在外部范围(如果未定义)中查找变量并且它确实有效,试试这个:
def o(n):
def i():
print("now in inner", n)
print("passed to outer", n)
i()
o(42)
现在如果你在一个内部作用域中定义一个同名变量,它将(在那个作用域中)隐藏在外部作用域中的变量,你可以给它赋任何值,你可以访问它,这一切在其范围内发生:
def o(n):
def i():
n = "in"
print("now in inner", n)
print("passed to outer", n)
i()
print("back in outer", n)
o(42)
那你为什么看到 UnboundLocalError
异常?因为 python 将考虑在该范围内分配给它的范围内的任何变量,如果在此类分配之前引用它,则不会在外部范围内访问它,而是认为尚未在本地分配:
def o(n):
def i():
print("now in inner", n)
n = "in"
print("passed to outer", n)
i()
print("back in outer", n)
o(42)
如果您按照评论中的建议添加 nonlocal
语句,错误就会消失,因为变量正在访问封闭范围而不是被视为本地,但这也意味着任何更改/(重新)分配也在影响外部范围,并且(尤其是在较大的程序中)可能会令人惊讶和困惑:
def o(n):
def i():
nonlocal n
print("now in inner", n)
n = "in"
print("passed to outer", n)
i()
print("back in outer", n)
o(42)
为了使相关位更紧密地联系在一起并明确关系,将变量的值传递给内部函数可能更好,执行它要执行的任何逻辑并让它 return 结果:
def o(n):
def i(inner_n):
print("now in inner", n)
inner_n += 1
return inner_n
print("passed to outer", n)
print("i() returned", i(n))
print("back in outer", n)
o(42)
The following constructs bind names: ... targets that are identifiers if occurring in an assignment ...
If a name is bound in a block, it is a local variable of that block, unless declared as nonlocal
or global
.
或者如前所述,赋值可能是该块中的最后一个动作,但这意味着变量在整个过程中都被视为本地变量(除非明确告知不要这样做)。
代码如下:
def cycle(f1, f2, f3):
"""Returns a function that is itself a higher-order function.
>>> def add1(x):
... return x + 1
>>> def times2(x):
... return x * 2
>>> def add3(x):
... return x + 3
>>> my_cycle = cycle(add1, times2, add3)
>>> identity = my_cycle(0)
>>> identity(5)
5
>>> add_one_then_double = my_cycle(2)
>>> add_one_then_double(1)
4
>>> do_all_functions = my_cycle(3)
>>> do_all_functions(2)
9
>>> do_more_than_a_cycle = my_cycle(4)
>>> do_more_than_a_cycle(2)
10
>>> do_two_cycles = my_cycle(6)
>>> do_two_cycles(1)
19
"""
"*** YOUR CODE HERE ***"
def execution(n):
def inner(x):
result = x
while (n > 0):
n = n - 1
if (n >= 0):
result = f1(result)
n = n - 1
if (n >= 0):
result = f2(result)
n = n - 1
if (n >= 0):
result = f3(result)
return result
return inner
return execution
运行 在终端测试
$ python -m doctest xx.py
得到错误:
UnboundLocalError: local variable 'n' referenced before assignment
我认为方法inner
中使用的n
变量可以从外部方法execution
中获取,因为在运行时,execution
必须是第一次调用是调用getinner
方法,所以变量n
肯定已经初始化了。我在这里犯了什么错误?我用的是python 3.8.1
发生了什么事,为什么?基于变量范围,您希望在外部范围(如果未定义)中查找变量并且它确实有效,试试这个:
def o(n):
def i():
print("now in inner", n)
print("passed to outer", n)
i()
o(42)
现在如果你在一个内部作用域中定义一个同名变量,它将(在那个作用域中)隐藏在外部作用域中的变量,你可以给它赋任何值,你可以访问它,这一切在其范围内发生:
def o(n):
def i():
n = "in"
print("now in inner", n)
print("passed to outer", n)
i()
print("back in outer", n)
o(42)
那你为什么看到 UnboundLocalError
异常?因为 python 将考虑在该范围内分配给它的范围内的任何变量,如果在此类分配之前引用它,则不会在外部范围内访问它,而是认为尚未在本地分配:
def o(n):
def i():
print("now in inner", n)
n = "in"
print("passed to outer", n)
i()
print("back in outer", n)
o(42)
如果您按照评论中的建议添加 nonlocal
语句,错误就会消失,因为变量正在访问封闭范围而不是被视为本地,但这也意味着任何更改/(重新)分配也在影响外部范围,并且(尤其是在较大的程序中)可能会令人惊讶和困惑:
def o(n):
def i():
nonlocal n
print("now in inner", n)
n = "in"
print("passed to outer", n)
i()
print("back in outer", n)
o(42)
为了使相关位更紧密地联系在一起并明确关系,将变量的值传递给内部函数可能更好,执行它要执行的任何逻辑并让它 return 结果:
def o(n):
def i(inner_n):
print("now in inner", n)
inner_n += 1
return inner_n
print("passed to outer", n)
print("i() returned", i(n))
print("back in outer", n)
o(42)
The following constructs bind names: ... targets that are identifiers if occurring in an assignment ...
If a name is bound in a block, it is a local variable of that block, unless declared as
nonlocal
orglobal
.
或者如前所述,赋值可能是该块中的最后一个动作,但这意味着变量在整个过程中都被视为本地变量(除非明确告知不要这样做)。