我定義了一個名爲fab
的因子函數。我用的發電機,以避免棧overflow.But的東西我不明白過來時,我嘗試寫一個裝飾的版本,這是更直觀:當我將變量'x'更改爲'fab'時發生了什麼?關於修飾符並傳遞函數變量
import types
def TCO(f):
def inner(*nkw,**kw):
gen=f(*nkw,**kw)
while isinstance(gen,types.GeneratorType):
gen=gen.next()
return gen
return inner
def fab(n,s=1):
if n<2:
yield s
else:
yield fab(n-1,s*n)
x=TCO(fab)
print x(2500) #this works fine, overcoming the limitation of tail-recursion.
fab=TCO(fab) #now just change the variable name.
print fab(5) #this woks fine.
print fab(2500) #this will raise an error :maximum recursion limit exceeded
爲什麼?我知道它與fab
同名,但爲什麼fab(5)
工作正常?我認爲當我定義fab=TCO(fab)
時,我實際上將inner
中的f
引用的對象更改爲對象TCO(fab)
。所以當晶圓廠(5)運行時,gen
永遠不會是一個發電機!因爲inner
永遠不會返回發電機!
我瘋了......爲什麼?
能產生恰好一次應該是一臺發電機一個函數。 – Alfe
@Alfe情況是不同的,如果我使用'return',它與python中的普通尾遞歸形式相同並且遭受遞歸限制。 – tcpiper
您可以返回一個lambda以避免立即評估。我覺得在這裏使用一臺發電機並沒有清理乾淨,而是隱藏了真正的意圖。 – Alfe