2011-06-19 21 views
3

高価な関数f(x)を1回計算したいだけですが、かなり頻繁に呼び出されます。本質的には、関数が呼び出された最初のときには、xの範囲について値の集まりを計算する必要があります。なぜなら、とにかく積分されてスプラインで補間されるからです。さらなる使用。Python:関数内から関数を再定義する

私のアイデアは、実装が非常に簡単なので、次のようなことをしていました。最初に関数が呼び出され、何かをしてから、それ自体を再定義し、その後は何かを実行します。しかし、それは期待どおりに機能せず、一般に悪い習慣であるかもしれません。

def f(): 
    def g(): 
     print(2) 
    print(1) 
    f = g 
f() 
f() 

予想される出力:

1 
2 

実際の出力:

1 
1 

定義グラム()Fの外側には、()は役立ちません。なぜこれは機能しませんか?それ以外に、今私が考えることができる唯一の解決策は、いくつかのグローバル変数を使用することです。それとも何とかこのクラスを書くのは理にかなっていますか?

答えて

6

これはあまりにも複雑です。単に

@memoized 
def f(): 
    # expensive calculation here ... 
    return calculated_value 

のPython 3では、あなたはfunctools.lru_cachememoizedを置き換えることができ、その後

def memoized(f): 
    res = [] 
    def resf(): 
     if len(res) == 0 
      res.append(f()) 
     return res[0] 
    return resf 

と:代わりに、メモ化を使用します。

+0

+1:[memoization](http://en.wikipedia.org/wiki/Memoization)と[装飾](http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Decorators)、装飾を許可するPythonバージョン、行く方法です。正式な例[here](http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize) – Johnsyweb

+0

dictがunhashableであるという事実に問題はありませんか? – juanchopanza

+0

@juanchopanzaはい、はい。この例では不要な引数は削除されています。 – phihag

3

Fの範囲でfはあなたがFを変更したい場合は、あなたがグローバル使用することができ、関数の外には影響しません変更:

>>> def f(): 
...  print(1) 
...  global f 
...  f=lambda: print(2) 
... 
>>> f() 
1 
>>> f() 
2 
>>> f() 
2 
1

何を記述していることのために発明された問題のキャッシングの一種であります。なぜ結果を保持するためのバッファを持たないのでしょうか?高価な計算を行う前に、バッファがすでに充填されているかどうかを確認してください。そうであれば、バッファリングされた結果を返し、そうでなければ、計算を実行し、バッファを充填し、結果を返す。このために自己修正コードですべての夢を見る必要はありません。

+0

彼は真実を語る。アーメン(+1)。 – jkp

5

単純にf関数の先頭にglobal fを追加します。そうでない場合、pythonはローカルf変数を作成します。

3

memoizationdecorationを使用して結果をキャッシュできます。例hereを参照してください。役に立つと分かるかもしれないメモの別の質問は、hereで見つけることができます。

関連する問題