1

class Object(): pass を指定した場所にオブジェクトを定義しましA = Object()た。Ab、Ac などの属性の作成に進みました。ほとんどはリストであり、その項目のいくつかはリストです。私が書いた:

  outFile = file('A.obj','wb')
  pickle.dump(A,outFile)
  outFile.close()

エラーが発生しました:

PicklingError: Can't pickle <class '__main__.Object'>: it's not found as __main__.Object

私の目標は、オブジェクトをダンプ (および後でロード) できるようにすることです。

4

2 に答える 2

1

エラーは非常に明確です。次のような(または同等の)ことをしました:

>>> import pickle
>>> class Object(object): pass
... 
>>> A = Object
>>> del Object
>>> pickle.dumps(A)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/usr/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.7/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <class '__main__.Object'>: it's not found as __main__.Object

pickleこれは、のドキュメントで非常に明確に対処されています。

関数 (組み込みおよびユーザー定義) は、値ではなく「完全修飾」名参照によってピクルされることに注意してください。これは、関数が定義されているモジュールの名前とともに、関数名のみがピクルされることを意味します。関数のコードもその関数属性もピクルされません。したがって、定義モジュールは unpickling 環境でインポート可能である必要があり、モジュールには名前付きオブジェクトが含まれている必要があります。そうでない場合、例外が発生します。

同様に、クラスは名前付き参照によってピクルされるため、アンピクル環境と同じ制限が適用されます。クラスのコードやデータはピクルされていないことに注意してください

したがって、ピクル/アンピクル時にクラスの名前を使用できる必要があります。実行後:

>>> A = Object
>>> del Object

pickle しようとするとApickleモジュールはクラスにアクセスできるかどうかをチェックします。しかし、それA.__name__Objectそれを見つけることができず、ピクルス化に失敗するためです。


同じことがユーザー定義クラスのインスタンスにも当てはまることに注意してください。

同様に、クラス インスタンスが pickle 化される場合、それらのクラスのコードとデータは一緒に pickle 化されません。インスタンス データのみがピクルされます。これは意図的に行われるため、クラスのバグを修正したり、クラスにメソッドを追加したりしても、以前のバージョンのクラスで作成されたオブジェクトをロードできます。クラスの多くのバージョンを参照する長寿命のオブジェクトを計画している場合は、オブジェクトにバージョン番号を付けて、クラスの__setstate__()メソッドによって適切な変換が行われるようにすることをお勧めします。

于 2013-10-11T21:36:07.790 に答える
0

だから...あなたがこのようなものを構築していたとしましょう...これは、ファクトリメソッド内にクラスのインスタンスを構築します。次に、報告したエラーが発生します。トレースバックを見てください... pickle がしようとしているのはpickle.save_global、クラスをシリアル化するために使用することです。関数内に構築されていますが、__main__では、クラスは実際に名前が付けられ__main___.Objectます...そしてクラスはありません...名前空間__main__.Object内にネストされています。object_factoryPython では、クラス、インスタンス、関数、およびその他のオブジェクトを動的に構築するためにファクトリ メソッドがよく使用されます。ファクトリ メソッドを使用している場合は、代わりに、関数の代わりに別のクラス内にファクトリ メソッドを作成できます。これにより、ピッカーが Object クラスのインスタンスを現在よりもシリアル化できる可能性が高くなります。 .

>>> def object_factory(a,b):
...   c = a+b
...   class Object(object):
...     d = 1
...     e = [c, d, [1,2,3]]
...     def foo(self, x):
...       return (self.d * c) + (x * Object.e)
...   return Object()
... 
>>> A = object_factory([4,5],[6,7])
>>> A
<__main__.Object object at 0x973030>
>>> A.d
1
>>> A.e
[[4, 5, 6, 7], 1, [1, 2, 3]]
>>> A.foo(1)
[4, 5, 6, 7, [4, 5, 6, 7], 1, [1, 2, 3]]
>>> 
>>> _A = pickle.dumps(A)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 1366, in dumps
    Pickler(file, protocol).dump(obj)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 224, in dump
    self.save(obj)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 401, in save_reduce
    save(args)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 562, in save_tuple
    save(element)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 753, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <class '__main__.Object'>: it's not the same object as __main__.Object

コードを投稿するか、少なくとも問題を示すおもちゃのコードを投稿すると役立ちます。

于 2013-10-23T02:39:09.273 に答える