9

開発中に SOAP サーバーに繰り返しアクセスすることを避けるために、毎回サーバーにクエリを実行することなく残りのコードを実行できるように、結果をキャッシュしようとしています。

以下のコードではPicklingError: Can't pickle <class suds.sudsobject.AdvertiserSearchResponse at 0x03424060>: it's not found as suds.sudsobject.AdvertiserSearchResponse、泡の結果をピクルしようとすると が得られます。これは、クラスが動的に作成されるためだと思います。

import pickle
from suds.client import Client

client = Client(...)
result = client.service.search(...)

file = open('test_pickle.dat', 'wb')
pickle.dump(result, file, -1)
file.close()

-1からプロトコル バージョン を削除するpickle.dump(result, file, -1)と、別のエラーが発生します。

TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled

ピクルスは正しいことですか?私はそれを機能させることができますか?より良い方法はありますか?

4

2 に答える 2

9

現在表示されているエラー メッセージが伝えようとしているのは、(現在使用している古いレガシー pickle プロトコルでは) pickle 化できない__slots__インスタンスを pickle しようとしているということです__getstate__

ただし、クラスを変更しても、他の問題に遭遇するため、役に立ちません。これは、動的に生成されたクラスが原因である可能性が高いと既に正しく識別しています。すべてのpickleプロトコルは、クラス (および関数) を「名前で」シリアライズし、基本的にモジュール内の最上位の名前になるように制約します。また、インスタンスをシリアル化するには、クラスをシリアル化する必要あります (クラスが存在しない場合、後でインスタンスを再構築するにはどうすればよいでしょうか?!)。

そのため、他の方法でデータを保存して再読み込みする必要があります。具体的なクラスへの現在の直接的な依存を断ち切り、そのような具体的なクラスのsuds.sudsobject両方で実装できるインターフェイス (形式化されているか、ダックタイピングによって定義されているだけ) に依存することを優先します。実際にSOAPサーバーにアクセスしている場合のクラス、またはファイルからデータをロードしている場合のより単純な「自家製」のクラス。(インスタンスの状態を表すデータは間違いなく dict として表すことができるので、本当に必要な場合は pickle を介してそれをcopy_reg強制することができます。 -侵襲的に[[追加することはできません__getstate__など]] -- このようなオブジェクト間に相互参照の豊富なメッシュがある場合にのみ、問題が発生します)。

于 2010-01-30T17:45:01.230 に答える
3

クラスのインスタンスオブジェクトではなく、クラスオブジェクト自体を酸洗いしています。クラスオブジェクトが再作成された場合、これは機能しません。ただし、クラス オブジェクトが存在する限り、クラスのピクル インスタンスは機能します。

于 2010-01-30T13:11:44.963 に答える