2

という名前の階乗関数を定義します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) が実行されるとき、 は決してジェネレーターにはなりません! ジェネレーターは決して返されないためです。finnerTCO(fab)geninner

私は怒っています...なぜですか?

4

3 に答える 3