我有一個簡單的memoizer裝飾:memoize的裝飾未能memoize的(不使用修飾語法時)
def funcmemo(f):
memo = {}
@wraps(f)
def wrapper(*args):
if args in memo:
return memo[args]
else:
temp = f(*args)
print "memoizing: ", args, temp
memo[args] = temp
return temp
return wrapper
現在,當我通過 「@」 符號使用,
@funcmemo
def fib(n):
print "fib called with:", n
if n < 2: return n
return fib(n-2) + fib(n-1)
res = fib(3)
print "result:", res
它工作正常,如在打印輸出中看到:
fib called with: 3
fib called with: 1
memoizing: (1,) 1
fib called with: 2
fib called with: 0
memoizing: (0,) 0
memoizing: (2,) 1
memoizing: (3,) 2
result: 2
然而,當我這樣做:
def fib(n):
print "fib called with:", n
if n < 2: return n
return fib(n-2) + fib(n-1)
memfib = funcmemo(fib)
res = memfib(3)
print "result:", res
顯然未修飾的FIB被調用,只有最後的返回值「達到」高速緩存(顯然產生了巨大的經濟放緩):
fib called with: 3
fib called with: 1
fib called with: 2
fib called with: 0
fib called with: 1
memoizing: (3,) 2
result: 2
奇怪的是,這一個正常工作:
def fib(n):
print "fib called with:", n
if n < 2: return n
return fib(n-2) + fib(n-1)
fib = funcmemo(fib)
res = fib(3)
print "result:", res
而且,同樣的事情發生與基於類的版本:
class Classmemo(object):
def __init__ (self, f):
self.f = f
self.mem = {}
def __call__ (self, *args):
if args in self.mem:
return self.mem[args]
else:
tmp = self.f(*args)
print "memoizing: ", args, temp
self.mem[args] = tmp
return tmp
使用「匿名」裝飾功能時,就像
res = Classmemo(fib)(3)
我會很高興得到啓發關於這背後的原因也發生
的問題。
是的,你是對的。但你的問題在哪裏? – Alfe 2012-03-22 09:54:43