cPickle
ロギングに使用されるデータをシリアル化するために使用しています。
必要なものをオブジェクトにスローしてから、シリアル化できるようにしたいと考えています。通常、これはcPickle
で問題ありませんが、シリアライズしたいオブジェクトの 1 つに関数が含まれているという問題が発生しました。これによりcPickle
、例外が発生しました。
プロセス全体を内破させるのではなくcPickle
、処理できないものをスキップするだけです。
これを実現するための良い方法は何ですか?
私は、あなたがベストエフォート型の解決策を探していて、ピクルされていない結果が適切に機能しなくても大丈夫だと仮定しています.
特定のユース ケースでは、関数オブジェクトの pickle ハンドラーを登録したい場合があります。ベストエフォートの目的に十分なダミーハンドラーにするだけです。関数のハンドラーを作成することは可能ですが、かなり注意が必要です。pickle 化する他のコードへの影響を避けるために、ロギング コードを終了するときにハンドラーの登録を解除することをお勧めします。
以下に例を示します (登録解除なし):
import cPickle
import copy_reg
from types import FunctionType
# data to pickle: note that o['x'] is a lambda and they
# aren't natively picklable (at this time)
o = {'x': lambda x: x, 'y': 1}
# shows that o is not natively picklable (because of
# o['x'])
try:
cPickle.dumps(o)
except TypeError:
print "not natively picklable"
else:
print "was pickled natively"
# create a mechanisms to turn unpickable functions int
# stub objects (the string "STUB" in this case)
def stub_pickler(obj):
return stub_unpickler, ()
def stub_unpickler():
return "STUB"
copy_reg.pickle(
FunctionType,
stub_pickler, stub_unpickler)
# shows that o is now picklable but o['x'] is restored
# to the stub object instead of its original lambda
print cPickle.loads(cPickle.dumps(o))
それは印刷します:
not natively picklable
{'y': 1, 'x': 'STUB'}