cPickle を使用してダンプしたものをロードしようとすると、次のエラー メッセージが表示されます。
ValueError: insecure string pickle
ダンプとロードの両方の作業が同じコンピューターで行われるため、同じ OS: Ubuntu 8.04.
どうすればこの問題を解決できますか?
「世界中で1日に何十億回も使用されている機能のPython自体で観察されたことのないバグよりもはるかに可能性が高い」:クロスの人々がこれらのフォーラムに参加する方法には常に驚かされます。
この問題を解決する簡単な方法の1つは、データ構造のダンプに使用しているストリームを閉じるのを忘れることです。今やりました
>>> out = open('xxx.dmp', 'w')
>>> cPickle.dump(d, out)
>>> k = cPickle.load(open('xxx.dmp', 'r'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: insecure string pickle
そもそもここに来たのは、何を間違えたのかわからなかったからです。
そして、私はここに来るだけでなく、実際にそれについて考え、私がやるべきだったことに気づきました。
>>> out = open('xxx.dmp', 'w')
>>> cPickle.dump(d, out)
>>> out.close() # close it to make sure it's all been written
>>> k = cPickle.load(open('xxx.dmp', 'r'))
忘れやすい。彼らがばかだと言われる必要はありませんでした。
オープンモード「rb」が原因で、Python 2.7 で次のエラーが発生しました。
with open(path_to_file, 'rb') as pickle_file:
obj = pickle.load(pickle_file)
したがって、Python 2 の場合、「モード」は「r」にする必要があります。
また、Python 3 は Python 2 の pickle 形式をサポートしていないのではないかと思いました。Python 2 で作成された pickle ファイルを読み込もうとすると、次のようになります。
pickle.unpicklingerror: the string opcode argument must be quoted
このスレッドを確認してください。ピーター・オッテン 言います:
腐ったピクルス。ダンプ内の文字列が " または ' で開始および終了していない場合、エラーが発生します。
そのような「破損」を再現する簡単な方法を示します。Steve Holden は、フォローアップの投稿で、'rb' と 'wb' を一致させないことが問題を引き起こす別の方法であると示唆しています (ただし、Python 2 と Linux では、その特定の間違いは見過ごされるべきです)。
を使用してこのエラーが発生した場合youtube-dl
、この問題は修正されています: https://github.com/rg3/youtube-dl/issues/7172#issuecomment-242961695
richiecannizzo が 8 月 28 日にコメントしました
brew install libav
Macですぐに修正するか、
sudo apt-get install libav
#Linux の場合
dump()
との間のデータで何をしていますload()
か? バイナリ データ (VARCHAR、一部のデータベースの TEXT 列、一部のキー値ストレージ) に対して適切に機能しない方法で、テキスト モード (Windows の場合) で開かれたファイルまたはデータベース ストレージにピクルされたデータを格納することは、非常に一般的なエラーです。ストレージに渡してすぐに取り出したピクルされたデータを比較してみてください。
pickle が大きい場合、このエラーは python 2 (および python 3 の初期バージョン) でも発生する可能性があります ( Python Issue #11564 ):
Python 2.7.11 |Anaconda custom (64-bit)| (default, Dec 6 2015, 18:08:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://anaconda.org
>>> import cPickle as pickle
>>> string = "X"*(2**31)
>>> pp = pickle.dumps(string)
>>> len(pp)
2147483656
>>> ss = pickle.loads(pp)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: insecure string pickle
この制限は、python 3.4 ( PEP 3154 )で pickle プロトコル 4 が導入されたことで解決されました。残念ながら、この機能は python 2 にバックポートされておらず、おそらくこれからもありません。これが問題で、python 2 pickle を使用する必要がある場合、できる最善の方法は、pickle のサイズを小さくすることlist
ですlist
。
私はPython ValueError: insecure string pickle
別の方法でメッセージを受け取りました。
私にとっては、バイナリファイルをエンコードしてソケットbase64
を通過した後に発生しました。urllib2
最初はこのようなファイルをまとめていました
with open(path_to_binary_file) as data_file:
contents = data_file.read()
filename = os.path.split(path)[1]
url = 'http://0.0.0.0:8080/upload'
message = {"filename" : filename, "contents": contents}
pickled_message = cPickle.dumps(message)
base64_message = base64.b64encode(pickled_message)
the_hash = hashlib.md5(base64_message).hexdigest()
server_response = urllib2.urlopen(url, base64_message)
しかし、サーバー上では、一部のバイナリ ファイルに対してハッシュが異なって出力され続けました。
decoded_message = base64.b64decode(incoming_base64_message)
the_hash = hashlib.md5(decoded_message).hexdigest()
そして解凍はinsecure string pickle
メッセージを与えました
cPickle.loads(decoded_message)
しかし成功
私にとってうまくいったのは、使用することでしたurlsafe_b64encode()
base64_message = base64.urlsafe_b64encode(cPickle.dumps(message))
そしてデコードする
base64_decoded_message = base64.urlsafe_b64decode(base64_message)
参考文献
これは私に起こったことであり、人口の小さな部分かもしれませんが、それでも私は彼らのためにこれをここに掲載したいと思います:
インタープリター (Python3) は、入力ファイル ストリームが文字列ではなくバイト単位である必要があるというエラーを表示し、オープン モード引数を 'r' から 'rb' に変更した可能性があります。文字列が壊れていると言って、それがあなたがここに来た理由です。
このような場合の最も簡単なオプションは、Python2 (2.7 をインストールできます) をインストールしてから、Python 2.7 環境でプログラムを実行することです。これにより、問題なくファイルが unpickle されます。基本的に、ファイルを開くモードを rb から r に変更し、Python2 を使用してファイルを unpickle するだけで、実際に破損しているかどうかを確認するために文字列をスキャンするのに多くの時間を無駄にしました。だから私はこの情報をそこに置いているだけです。