提问人:teepee 提问时间:1/22/2022 更新时间:1/22/2022 访问量:137
从函数返回函数时出现作用域错误
Scope error when returning function from function
问:
我在 python 中使用函数生成器时遇到了问题,即从函数返回函数,其中一些输入是通过外部函数的参数定义的,从而产生一个具有较低 arity 的函数。我以前在其他情况下使用过这种方法,没有问题,但在这种情况下我遇到了错误,无法理解原因。我有以下函数来生成一个函数:
def func1(s: set, f: Callable) -> Callable:
def func2(x: int) -> dict:
while x:
s = s - {x}
x = f(x)
return s
return func2
f2 = func1({1,2,3,4}, lambda x: x-1)
如果我尝试,我会得到与该语句相关的错误。我不明白为什么它不是范围的一部分,因为我认为它在被调用创建时是固定的。f2(3)
"local variable 's' referenced before assignment"
s = s - {x}
s
func1
f2
我能够通过使用这种方法来解决这个问题:我将所有参数组合到一个函数中,说并使用该操作,该操作的行为符合预期:func3
functools.partial
from functools import partial
def func3(x: int, s: set, f: Callable) -> dict:
while x:
s = s - {x}
x = f(x)
return s
f2 = partial(func3, s={1,2,3,4}, f=lambda x: x-1)
当我打电话时,我得到了预期的。f2(3)
{4}
我的理解是,这两种方法应该产生相同的结果;但是,我显然遗漏了关于可变范围在第一种情况下如何运作的东西。任何见解将不胜感激。
答:
你的第一段代码的问题是里面有一个局部变量。它与你在 中定义的变量没有联系。请记住,在函数中分配给的任何变量都是局部变量,除非您另有声明。s
func2
s
func1
解决方法是将 添加到您的定义中。然后 Python 会意识到 inside 所指的和 inside 是一样的。nonlocal s
func2
s
func2
s
func1
@KellyBundy指出,这可能仍然不能给你你想要的东西。如果你只是简单地做非局部变量,你实际上是在说这两个变量指向同一个集合。所做的任何更改都是“永久性的”。第二次被调用,will 的值是第一次被调用结束时的任何值。目前尚不确定这是否是预期的。s
s
f2
s
f2
如果想在每次调用时都复位,则需要将两者分开。最简单的方法是从 开始,然后在 sfunc2s0func2' 中使用,可以根据需要进行修改。s
f2
s
func2
s0 = s
s0
func2. Since
is never modified within
, it refers to the outer variable. And you have a different variable
within
评论
nonlocal
partial
s
functional-programming
print(f2(2), f2(3), f2(2))
partial
s
上一个:如何避免闭包中布尔标志的突变?
下一个:关于“帧作为本地状态的存储库”
评论
print(f2(2), f2(3), f2(2))