0
def tracer(fn):    
    def traced(x):
       print('Calling',fn,'(',x,')')
       result=fn(x)
       print('Got',result,'from',fn,'(',x,')')
       return result
    return traced

def fact(n):   
 if n ==0:
    return 1
 return n * fact(n-1)

new_fact = tracer(fact)  
new_fact(2)

高階関数をよりよく理解するために pythontutor.com でこのコードを使用しましたが、ステップ 8 の new_fact(2) が traced にマップされる理由を理解するのが困難ですか? 言い換えれば、トレースされた関数は引数が 2 であることをどのように知るのでしょうか?

4

1 に答える 1

4

Python では、関数もオブジェクトです。関数を呼び出すとtracer()、ネストされたtraced()関数が返されます。実際には、その関数の新しいコピーを作成しています。

return traced

返された関数オブジェクトを に保存してnew_factから呼び出しました。

>>> tracer(fact)
<function traced at 0x10644c320>
>>> new_fact = tracer(fact)
>>> new_fact
<function traced at 0x10644c398>
>>> new_fact(2)
('Calling', <function fact at 0x10644c230>, '(', 2, ')')
('Got', 2, 'from', <function fact at 0x10644c230>, '(', 2, ')')
2

これは、任意の関数で行うことができます。関数への参照を別の名前で保存します。

>>> def foo(): print 'foo'
... 
>>> bar = foo
>>> bar()
foo
于 2013-08-17T09:36:06.440 に答える