2

高価な操作を実行し、頻繁に呼び出される関数があります。ただし、操作は 1 回だけ実行する必要があります。その結果はキャッシュできます。

無限ジェネレーターを作成しようとしましたが、期待した結果が得られませんでした:

>>> def g():
...     result = "foo"
...     while True:
...         yield result
... 
>>> g()
<generator object g at 0x1093db230>    # why didn't it give me "foo"?

なぜg発電機ではないのですか?

>>> g
<function g at 0x1093de488>

編集:このアプローチがうまくいかなくても問題ありませんが、次のように、通常の関数とまったく同じように実行するものが必要です。

>>> [g() for x in range(3)]
["foo", "foo", "foo"]
4

5 に答える 5

6

g()はジェネレータ関数です。それを呼び出すと、ジェネレーターが返されます。次に、そのジェネレーターを使用して値を取得する必要があります。たとえば、ループするか、次のようnext()に呼び出します。

gen = g()
value = next(gen)

再度呼び出すg()と、同じ値が再度計算され、新しいジェネレーターが生成されることに注意してください。

グローバルを使用して値をキャッシュしたいだけかもしれません。関数の属性としてそれを保存するとうまくいくかもしれません:

def g():
    if not hasattr(g, '_cache'):
        g._cache = 'foo'
    return g._cache
于 2013-07-31T18:05:51.057 に答える
4

より良い方法: @functools.lru_cache(maxsize=None). Python 2.7 にバックポートされているか、独自に作成することができます。

私は時折、次のことをして罪を犯します:

def foo():
    if hasattr(foo, 'cache'):
        return foo.cache

    # do work
    foo.cache = result
    return result
于 2013-07-31T18:09:47.667 に答える
1

より良いオプションはmemoizationを使用することです。結果をキャッシュする関数をラップするために使用できる memoize デコレータを作成できます。ここでいくつかの優れた実装を見つけることができます。

于 2013-07-31T18:07:44.580 に答える