1

Beaker のキャッシング ライブラリを使用しようとしていますが、機能しません。

これが私のテストコードです。

class IndexHandler():
    @cache.cache('search_func', expire=300)
    def get_results(self, query):
        results = get_results(query)
        return results

    def get(self, query):
        results = self.get_results(query)
        return render_index(results=results)

Beakerのドキュメントの例を試しましたが、表示されるのは

<type 'exceptions.TypeError'> at /
can't pickle generator objects

明らかに何かが欠けていますが、解決策が見つかりませんでした。

ちなみにこの問題はキャッシュタイプが「ファイル」に設定されている場合に発生します。

4

3 に答える 3

3

ファイルシステムに保存するようにビーカーを設定すると、各引数もピクルされていることが簡単にわかります。例:

tp3
sS'tags <myapp.controllers.tags.TagsController object at 0x103363c10> <MySQLdb.cursors.Cursor object at 0x103363dd0> apple'
p4

キャッシュの「キー」には、キーワード「apple」だけでなく、インスタンス固有の情報が含まれていることに注意してください。特に「自己」は呼び出し間で同じではないため、これはかなり悪いことです。キャッシュは毎回ミスになります (そして、役に立たないキーでいっぱいになります)。

キャッシュ アノテーションを含むメソッドには、考えている「キー」に対応する引数のみを指定する必要があります。これを言い換えると、"John" が値 555-1212 に対応するという事実を保存し、これをキャッシュしたいとします。関数は、引数として文字列以外のものを取らないでください。渡す引数は、呼び出しから呼び出しまで一定である必要があるため、「self」のようなものは不適切です。

これを機能させる簡単な方法の 1 つは、キー以外に何も渡す必要がないように、関数をインライン化することです。例えば:

def index(self):

    # some code here

    # suppose 'place' is a string that you're using as a key. maybe
    # you're caching a description for cities and 'place' would be "New York"
    # in one instance

    @cache_region('long_term', 'place_desc')
    def getDescriptionForPlace(place):
      # perform expensive operation here
      description = ...
      return description

    # this will either fetch the data or just load it from the cache
    description = getDescriptionForPlace(place)

キャッシュ ファイルは次のようになります。「place_desc」と「John」のみがキーとして保存されていることに注意してください。

tp3 
sS'place_desc John' 
p4
于 2011-01-02T17:04:33.760 に答える
1

beakerドキュメントではこれについて明示的に言及されていないことがわかりますが、明らかに、decorate 関数は呼び出された引数をピクルする必要があります (キャッシュへのキーの一部として使用し、エントリが存在するかどうかを確認し、そうでない場合は後で追加します) ) -- そして、エラー メッセージが示しているように、ジェネレータ オブジェクトは pickleable ではありません。もちろん、これはそれqueryがジェネレーターオブジェクトであることを意味します。

ビーカーやその他の種類のキャッシュを使用するためにすべきことは、queryジェネレーター オブジェクトの代わりに、そのクエリを構築できる (pickleable) オブジェクト (parameters文字列、数値、辞書、リスト、タプルなど) を渡すことです。などは、 の関数本体内のみで「ジャスト イン タイム」からクエリを作成し、簡単に配置できるように構成されていますget_results。このようにして、引数は pickleable になり、キャッシュが機能します。

都合がよければ、インスタンスがクエリを「表し」、必要な初期化とパラメーター設定をエミュレートし、実際のクエリオブジェクトを必要とするメソッドが呼び出されたときにのみジャストインタイムのインスタンス化を実行する単純な pickleable クラスを構築できます。しかし、それは単なる「便利な」アイデアであり、前の段落で説明した基本的な概念を変更するものではありません。

于 2010-07-03T16:05:31.287 に答える
1

return list(results)代わりに 試してみてreturn results、それが役立つかどうかを確認してください。

ビーカー ファイル キャッシュは、キャッシュ キーと値の両方をピクルできる必要があります。ほとんどのイテレータとジェネレータは unpickleable です。

于 2010-07-10T16:47:55.253 に答える