即使在递归调用中,“非本地”变量是不是总是从外部循环继承?
Posted
技术标签:
【中文标题】即使在递归调用中,“非本地”变量是不是总是从外部循环继承?【英文标题】:Does 'nonlocal' variable always inherit from the outer loop, even in recursive calls?即使在递归调用中,“非本地”变量是否总是从外部循环继承? 【发布时间】:2021-09-23 09:02:15 【问题描述】:我已经编写了一些代码,最近在编写函数的函数时遇到了“非本地”的需求(在处理递归时遇到了这个问题)。
例如:
def swapPairs(head):
head = None
def helper(node):
nonlocal head
...
head= nex.next
return helper(node.next)
我的问题很简单,因为我们调用递归函数 helper(node.next)
,然后循环回到 nonlocal head
- head
的值是否为 None (由于非本地头)?或者它是否保留了在之前的递归调用中分配给它的head = nex.next
?
所以我想了解'nonlocal head'
是否会导致head
总是取其在外部函数中分配的值,还是不是这种情况?相反,它只是一种在内部函数中初始化 head 的方法,因此它只能通过获取外部函数中定义的初始值来开始。
【问题讨论】:
【参考方案1】:nonlocal
和global
声明用于词法 作用域——松散地说,它们只关心源代码布局。
def swapPairs(head):
head = None # `head` in lexically outer scope <═╗
# ║
def helper(node): # ║
nonlocal head # nonlocal `head` for inner lexical scope >═╣
... # ║
head= nex.next # nonlocal applies to every use >═╝
return helper(node.next)
值得注意的是,作用域与代码的运行时嵌套无关;它不关心helper
是否被swapPairs
、helper
s 的序列或一些不相关的函数调用:helper
内部的名称head
完全等同于swapPairs
内部的名称head
.
这意味着def helper
中的head
将始终 引用定义def helper
的swapPairs
调用中的head
。一旦对helper
的第一次调用分配了head = nex.next
,这将更改head
内的swapPairs
,随后对helper
的调用将看到(并修改)这个新值。
【讨论】:
谢谢先生,很好的解释。但为了确认我理解正确,当我们在第一次递归调用时调用 helper(node.next) 时说,当我们运行 helper() 函数时,head=nex.next 而不是 head=None。这是正确的吗? 我确实理解您所说的“def helper 中的 head 将始终引用 swapPairs 中的 head” - 但是,在 swapPairs 中第一次调用 head=None 之后,我们不会访问/调用swapPairs 了。所以我想确认 head=None 永远不会到达。 @PatrickChong 实际上,除非helper
(或捕获head
的任何其他函数)分配head = None
,否则它不会返回None
。 swapPairs
中的 head = None
仍然只是一个按常规顺序执行的常规语句,以后不会隐式重新运行。以上是关于即使在递归调用中,“非本地”变量是不是总是从外部循环继承?的主要内容,如果未能解决你的问题,请参考以下文章