24

ピクルしたいさまざまなタイプのオブジェクトのリストがあります。漬けられるものだけ漬けたい。オブジェクトをピクルしようとする以外に、オブジェクトがピクル可能タイプであるかどうかを確認する標準的な方法はありますか?

ドキュメンテーションによると、ピクリング例外が発生した場合、それはすでに一部のバイトがファイルに書き込まれた後である可能性があるため、テストとしてオブジェクトをピクルしようとするのは良い解決策とは思えません。

この投稿を見ましたが、私の質問には答えていません。

4

3 に答える 3

27

まさにそれを行うパッケージdill.picklesメソッドがあります。dill

>>> class Foo(object):
...   x = iter([1,2,3])
... 
>>> f = Foo()     
>>> 
>>> dill.pickles(f)
False

のメソッドを使用しdillて、失敗の原因を探すことができます。

>>> dill.detect.badtypes(f)
<class '__main__.Foo'>
>>> dill.detect.badtypes(f, depth=1)
{'__setattr__': <type 'method-wrapper'>, '__reduce_ex__': <type 'builtin_function_or_method'>, '__reduce__': <type 'builtin_function_or_method'>, '__str__': <type 'method-wrapper'>, '__format__': <type 'builtin_function_or_method'>, '__getattribute__': <type 'method-wrapper'>, '__class__': <type 'type'>, '__delattr__': <type 'method-wrapper'>, '__subclasshook__': <type 'builtin_function_or_method'>, '__repr__': <type 'method-wrapper'>, '__hash__': <type 'method-wrapper'>, 'x': <type 'listiterator'>, '__sizeof__': <type 'builtin_function_or_method'>, '__init__': <type 'method-wrapper'>}
>>> dill.detect.badtypes(f, depth=1).keys()
['__setattr__', '__reduce_ex__', '__reduce__', '__str__', '__format__', '__getattribute__', '__class__', '__delattr__', '__subclasshook__', '__repr__', '__hash__', 'x', '__sizeof__', '__init__']

したがって、クラスの「組み込み」メソッドではない唯一の失敗はx…なので、ここから始めるのが良いでしょう。「x」にチェックを入れて、問題があれば別のものに置き換えましょう。

>>> dill.pickles(Foo.x)
False
>>> Foo.x = xrange(1,4)
>>> dill.pickles(Foo.x)
True

うん、失敗を引き起こしていて、ピクルできるので作品xに置き換える。やるべきことは何ですか?xrangedillxrange

>>> dill.detect.badtypes(f, depth=1).keys()
[]
>>> dill.detect.badtypes(f, depth=1)       
{}
>>> dill.pickles(f)                 
True
>>> 

xどうやら (クラス内のへの参照が pickle になったためと思われます__dict__)、今は pickle にfなっているようです…これで完了です。

dillまたtrace、オブジェクトを酸洗する際の正確なパスを表示することもできます。

>>> dill.detect.trace(True)
>>> dill.pickles(f)
T2: <class '__main__.Foo'>
F2: <function _create_type at 0x10e79b668>
T1: <type 'type'>
F2: <function _load_type at 0x10e79b5f0>
T1: <type 'object'>
D2: <dict object at 0x10e7c6168>
Si: xrange(1, 4)
F2: <function _eval_repr at 0x10e79bcf8>
D2: <dict object at 0x10e7c6280>
True
于 2015-08-25T14:36:48.960 に答える
6

この場合、私はダックテストを提案します。適切と思われる一時ファイルまたはメモリ ファイルにピクルしてみてください。失敗した場合は結果を破棄し、名前の変更に成功した場合は破棄します。

なんで?

Python では、オブジェクトにいくつかのプロパティがあるかどうかを 2 つの方法で確認できます。

object がAbstract Base Classのインスタンスであるかどうかを確認します。たとえばNumber、「数値階層のルートです。引数 x が数値であるかどうかだけを確認したい場合は、種類を気にせずに isinstance(x, Number) を使用してください。」

または、試してから例外を処理してください。これは多くの場合に発生します。pythonic 哲学はアヒルに基づいています。ダックタイピングダックテストEAFPがキーワードです。

最初のものは、コミュニティの一部からの圧力の下で python3 で適切に導入されたとさえ信じていますが、多くの人はまだダックが python を使用する方法であると強く信じています。

私の知る限り、チェックできる特別な前提条件はなくABC、酸洗の場合にそのオブジェクトをチェックできるものもありません。残っているのはアヒルだけです。

たぶん、何か他のことを試みることができますが、おそらくそれは価値がありません. オブジェクトがピクルス化に適しているかどうかを事前に調べるために、オブジェクトを手動でイントロスペクションするのは非常に困難です。

于 2013-07-26T04:06:44.280 に答える