2013-01-13 4 views
5

私はcPickleを使ってロギングに使用するデータをシリアル化しています。cPickle - 例外を発生させる代わりにシリアル化できないものを無視する

私はオブジェクトに必要なものを投げて、それをシリアル化したいと思っています。通常これはcPickleで問題なく、シリアル化したいオブジェクトの1つに関数が含まれているという問題が発生しました。これにより、cPickleが例外を発生させました。

私は、むしろcPickleを処理するだけで処理できないものをスキップして、全体のプロセスを中断させるのではありません。

これを行うにはどうすればよいでしょうか?

+4

育った例外をキャッチしますか? –

+2

例外をキャッチすることは助けにはならないでしょう。 – user4815162342

答えて

2

私はあなたがベストエフォート型のソリューションを探していると仮定していますが、アンピリリングされた結果が正しく機能しない場合は問題ありません。

特定の使用例については、関数オブジェクトの場合はregister a pickle handlerが望ましい場合があります。ベストエフォートの目的のために十分なダミーのハンドラにしてください。関数のハンドラを作ることは可能ですが、ややこしいことです。 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'} 
-1

なぜ例外をトラップしないのですか?あなたが他のすべてを保つために、これを行うことができます

try: 
    cPickle.dumps(obj) 
except cPickle.PicklingError: 
    pass 

、あまりにも...

>>> def safe_pickle(L): 
...  result = [] 
...  for target in L: 
...    try: 
...      result.append(cPickle.dumps(target)) 
...    except (cPickle.PicklingError, TypeError): 
...      result.append(None) 
...  return result 
... 
>>> safe_pickle(["A",open('file.txt')]) 
["S'A'\n.", None] 

キャッチ例外は発生しません。

+3

その場合、シリアル化したいものは保存されませんでした。それは対処できない特定のフィールドをスキップし、それ以外はすべてシリアル化する必要があります。 –

+0

@ChrisDutrow私の編集した答えを見てください。 :)私はそれが助けて欲しい。 –

+5

@frb pickleしようとしているオブジェクトの(深くネストされた)属性をpickleできない場合でも、これは失敗します。 –

0

を、cloudpickleを試してみてください。

>>> import cloudpickle 
>>> squared = lambda x: x ** 2 
>>> pickled_lambda = cloudpickle.dumps(squared) 

>>> import pickle 
>>> new_squared = pickle.loads(pickled_lambda) 
>>> new_squared(2) 
4 

we can pickle that

pip install cloudpickleあなたの夢を生きてください。同じ夢がdask、IPython並列、PySparkで生きていました。

関連する問題