编辑:我没有做好解释我的问题。我对关闭如何感到困惑,函数似乎记住了它以前的环境,但通过递归调用它似乎找到了名称的更新值。装饰递归函数
我的困惑通过Thomas Ballinger "Finding closure with closures" talk完美解决:一个可变的
范围在定义被确定,可变值在执行被确定。
因此,无论是递归还是闭包,名称的绑定都是在定义时定义的,但该值可以在之后进行更新。
原题:
装饰上的递归函数工作,而无需任何额外的努力:
def debug(f):
def new_f(*args, **kwargs):
print('arguments:', *args, **kwargs)
return f(*args, **kwargs)
return new_f
@debug
def f(n):
if n > 1:
return f(n-1)*n # f refers to the decorated version!
else:
return 1
在蟒蛇什么机制保证在线路f
return f(n-1)*n
点的f
装饰版本,而不是到原版的?
我认为一个函数在定义的时候会记住它的上下文(因此,使用闭包,内部函数可以使用来自外部函数的对象)。但是当定义f
时,修饰器还没有被应用,所以f
里面的功能f
是指永久的未修饰版本?显然,我误解了函数范围/上下文规则中的某些内容,但是什么?
更多的是缺乏使其指向其他任何地方的机制。请记住,'@ debug'只是用于定义函数的语法糖,然后调用'f = debug(f)',无论您在哪里寻找'f',您现在都可以获得装饰版本。 – jonrsharpe