2

Bar独自の状態とコールバックを効果的に持ち、別のクラス ( ) によって使用されるクラス ( )Fooがあります。

 class Foo(object):

     def __init__(self):
         self._bar = Bar(self.say, 10)
         self._bar.work()

     def say(self, msg):
         print msg

 class Bar(object):
     def __init__(self, callback, value):
         self._callback = callback
         self._value = value
         self._more = { 'foo' : 1, 'bar': 3, 'baz': 'fubar'}

     def work(self):
         # Do some work
         self._more['foo'] = 5
         self._value = 10
         self._callback('FooBarBaz')

 Foo()

明らかに、インスタンスメソッドがあるため、クラスをピクルすることはできないFooため、 &を保存するために&をBar実装する次のソリューションが残されていますが、メソッドもインスタンス化する必要があります(つまり、コールバック関数を渡す外部クラスからの呼び出し) .__getstate____setstate__Barself._valueself._moreself._callback__init__()Foo

しかし、これを達成する方法がわかりません。

どんな助けでも大歓迎です。
ありがとう。

4

1 に答える 1

1

このようなものをシリアル化する必要がある場合は、コールバックを文字列として定義できる必要があると思います。たとえば、次のように言うかもしれませんcallback = 'myproject.callbacks.foo_callback'

基本的には、関数を後で関数を検索するために使用できるものに__getstate__置き換えます。_callbackself._callback.__name__

では、関数__setstate__に置き換え_callbackます。

これは、関数がすべて実名を持つことに依存しているため、ラムダをコールバックとして使用してシリアル化することを期待できませんでした。また、関数を名前で検索するための合理的なメカニズムも必要です。

あなたは潜在的に使用することができます__import__(「myproject.somemodule.somefunc」のようなドット名の構文はそのようにサポートされる可能性があります。http://code.google.com/p/mock/source/browse/mock.py#1076を参照してください)またはコードでルックアップ テーブルを定義するだけです。

ルックアップテーブルで定義された可能なコールバックの小さなセットがあると仮定した簡単な (テストされていない、申し訳ありません!) 例:

def a():
    pass

callbacks_to_name = {a: 'a'
                     # ...
                     }

callbacks_by_name = {'a': a,
             # ...
             }

class C:
    def __init__(self, cb):
        self._callback = cb

    def __getstate__(self):
        self._callback = callbacks_to_name[self._callback]
        return self.__dict__

    def __setstate__(self, state):
        state[_callback] = callbacks_by_name[self._callback]

あなたのユースケースが何であるかはわかりませんが、作業項目を JSON または XML にシリアライズし、それらを自分でシリアライズおよびデシリアライズするための単純な関数セットを作成することをお勧めします。

利点は、シリアル化された形式を人間が読み取って理解できることと、ソフトウェアをアップグレードするときに変更できることです。Pickle は十分に近いように見えるので魅力的ですが、深刻な山が__getstate__あり__setstate__、アプリケーション専用の独自のスキームを構築するための労力や頭痛の種を実際に節約することはできません。

于 2012-08-06T15:46:42.563 に答える