という名前の階乗関数を定義します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)
うまくいくのですか? を定義するとき、 in で参照されるfab=TCO(fab)
オブジェクトを実際に object に変更すると思います。したがって、 fab(5) が実行されるとき、 は決してジェネレーターにはなりません! ジェネレーターは決して返されないためです。f
inner
TCO(fab)
gen
inner
私は怒っています...なぜですか?