当我尝试加载使用 cPickle 转储的内容时,我收到错误消息:
ValueError: insecure string pickle
转储和加载工作都在同一台计算机上完成,因此使用相同的操作系统:Ubuntu 8.04。
我该如何解决这个问题?
“在全世界每天使用数十亿次的功能中,比 Python 本身从未观察到的错误更有可能”:这总是让我惊讶于人们在这些论坛中的交流方式。
解决此问题的一种简单方法是忘记关闭用于转储数据结构的流。我已经做了
>>> 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 'mode' 应该是 '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 上,该特定错误应该被忽视)。
你对 和 之间的数据做了dump()
什么load()
?将腌制数据存储在以文本模式(在 Windows 上)打开的文件中或以二进制数据(VARCHAR、某些数据库中的 TEXT 列、某些键值存储)无法正常工作的方式存储在数据库存储中是很常见的错误。尝试比较您传递到存储并立即从中检索的腌制数据。
如果有人在使用时遇到此错误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上
如果您的泡菜很大( Python 问题 #11564 ) ,python 2(和早期版本的 python 3)也可能出现此错误:
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 泡菜,那么您能做的最好的事情就是减小泡菜的大小,例如,不是酸洗 a ,而是list
将元素单独腌制成 alist
泡菜。
在 Windows 上用 python 创建并在 linux 上用 python 重新加载的文件也存在同样的问题。解决方案:在 linux 中阅读之前对文件进行 dos2unix:作为一种魅力!
我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()
并且 unpickling 给出了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 环境中运行您的程序,因此它可以毫无问题地解压您的文件。基本上,我浪费了很多时间来扫描我的字符串,看看它是否确实损坏了,而我所要做的就是将打开文件的模式从 rb 更改为 r,然后使用 Python2 解压文件。所以我只是把这些信息放在那里。
我早些时候遇到过这个问题,找到了这个线程,并假设我对其中几个答案中提到的文件关闭问题免疫,因为我使用了一个with
语句:
with tempfile.NamedTemporaryFile(mode='wb') as temp_file:
pickle.dump(foo, temp_file)
# Push file to another machine
_send_file(temp_file.name)
但是,由于我从内部推送临时文件,该with
文件仍未关闭,因此我推送的文件被截断。这导致在insecure string pickle
读取远程计算机上的文件的脚本中出现相同的错误。
对此有两个潜在的修复:保持文件打开并强制刷新:
with tempfile.NamedTemporaryFile(mode='wb') as temp_file:
pickle.dump(foo, temp_file)
temp_file.flush()
# Push file to another machine
_send_file(temp_file.name)
或者在对其进行任何操作之前确保文件已关闭:
file_name = ''
with tempfile.NamedTemporaryFile(mode='wb', delete=False) as temp_file:
file_name = temp_file.name
pickle.dump(foo, temp_file)
# Push file to another machine
_send_file(file_name)