python - Python内部方法无法从外部方法获取变量
问题描述
下面的代码:
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
我认为方法中n
使用的变量inner
可以从外部方法中获取execution
,就像在运行时一样,execution
必须先调用才能inner
调用方法,所以变量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)
为了使相关位更紧密并明确关系,最好将变量的值传递给内部函数,执行它要执行的任何逻辑并让它返回结果:
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)
指向文档:
以下构造绑定名称: ... 如果出现在分配中,则作为标识符的目标 ...
如果名称绑定在块中,则它是该块的局部变量,除非声明为
nonlocal
orglobal
。
或者如前所述,赋值可能是该块中的最后一个操作,但这意味着该变量始终被视为局部变量(除非明确告知不要这样做)。
推荐阅读
- java - java中如何处理像“@PathParam(”“)”这样的java注解?我们在哪里可以找到特定注释处理器的源代码?
- image - 使用 arsd nanovega 渲染到位图
- javascript - 将 randomID 函数从 JS 移植到 PHP
- excel - 如何获取代码以每次在新工作表中逐行重复编程操作
- python - 我需要帮助在 Python 代码中进行数据排序
- python - 如何读取 json 文件并将数据写入 python3 中的 csv 文件?
- clojure - Clojure:从参考中删除项目?
- java - Difference between doOnSuccess and doOnEach, and in which use case i should use each of them
- python - 如何处理日志消息模板中的 Python 格式错误?
- excel - 判断 ActiveSheet.Pictures.Insert(Filename).Select 是否失败的方法?