为什么这样:
def fn(proc, *args, **kwargs):
cache = proc.cache = {}
def cached_execution(cache, *args, **kwargs):
if proc in cache:
if args in cache[proc]:
return cache[proc][args]
res = proc(args)
cache[proc] = {args: res}
return res
return cached_execution(cache, proc, *args, **kwargs)
@fn
def cached_fibo(n):
if n == 1 or n == 0:
return n
else:
return cached_fibo(n-1) + cached_fibo(n-2)
print cached_fibo(100)
抛出这样的例外:
NameError:未定义全局名称“cached_fibo”
我错过了什么基本概念?
(从概念上讲,**kwargs
仅用于装饰。不用于检索缓存结果,但不用担心它。)
答案 0 :(得分:3)
装饰器应该返回一个函数,而不是调用函数的结果。
但是这导致我们犯下一个错误:当你将cache
和proc
传递给cached_execution
函数时,它们会落在*args
中,然后传递给proc
}。这没有意义。只需在内部方法中捕获cache
和proc
:
def fn(proc, *args, **kwargs):
cache = proc.cache = {}
def cached_execution(*args, **kwargs):
if proc in cache:
if args in cache[proc]:
return cache[proc][args]
res = proc(*args)
cache[proc] = {args: res}
return res
return cached_execution
另一个问题:你没有解包args
。您应该拨打proc(*args)
而不是proc(args)
(已在上面修复过)。
答案 1 :(得分:1)
包装器似乎有点格格不入。这是一个更新版本:
def fn(proc):
cache = proc.cache = {}
def cached_execution(*args, **kwargs):
if proc in cache:
if args in cache[proc]:
return cache[proc][args]
res = proc(args[0])
cache[proc] = {args: res}
return res
return cached_execution
您试图在包装器中运行包装器函数,而不是将其返回以作为函数运行,从而导致问题。
下一个问题是,当您只想要第一个时,您提供的参数是*args
的元组proc(args)
列表,因此需要转换为proc(args[0])