Python 3.x 在python/numpy中从转换的字符串取消勾选

Python 3.x 在python/numpy中从转换的字符串取消勾选,python-3.x,numpy,pickle,Python 3.x,Numpy,Pickle,我有大量的numpy Ndarray存储在字符串中。这可能是一个糟糕的设计选择,但我就是这么做的,现在拾取的字符串似乎已经被转换了,或者一路上发生了什么事情,当我尝试取消拾取时,我注意到它们的类型为str,我得到以下错误: TypeError: 'str' does not support the buffer interface 当我调用 numpy.loads(bin_str) 其中,bin_str是我试图解开的东西。如果我打印出bin_str它看起来像 b'\x80\x02cnumpy

我有大量的numpy Ndarray存储在字符串中。这可能是一个糟糕的设计选择,但我就是这么做的,现在拾取的字符串似乎已经被转换了,或者一路上发生了什么事情,当我尝试取消拾取时,我注意到它们的类型为
str
,我得到以下错误:

TypeError: 'str' does not support the buffer interface
当我调用

numpy.loads(bin_str)
其中,
bin_str
是我试图解开的东西。如果我打印出
bin_str
它看起来像

b'\x80\x02cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\x01K\x00\x85q\x02c_codecs\nencode\nq\x03X\x01\x00\x00\ ...
继续一段时间,所以信息似乎就在那里,我只是不太确定如何将其转换为numpy/pickle所需的任何字符串格式。一时兴起,我试了一下

numpy.loads( bytearray(bin_str, encoding='utf-8') )

它们都会抛出一个错误
\u pickle.UnpicklingError:unpickling stack underflow
。有什么想法吗

PS:我使用的是python 3.3.2和numpy 1.7.1

编辑

我发现如果我这样做:

open('temp.txt', 'wb').write(...)
return numpy.load( 'temp.txt' )
我取回我的数组,
表示从另一个窗口复制和粘贴
print(bin_str)
的输出。我曾尝试将
bin_str
直接写入一个文件以取消勾选,但这不起作用,它抱怨
TypeError:“str”不支持缓冲区接口。将
bin_str
转换为可以直接写入二进制文件的内容的一些合理方法会在试图读回二进制文件时导致pickle错误

编辑2 所以我猜发生的事情是,我的二进制pickle字符串最终被编码在一个普通字符串中,比如:

"b'pickle'"
这是不幸的,我还没有弄明白如何处理这件事,除了用这种荒谬而复杂的方式把它弄回来:

open('temp.py', 'w').write('foo = ' + bin_str)
from temp import foo
numpy.loads( foo )

这似乎是一个非常可耻的解决方案,所以请给我一个更好的

听起来您保存的字符串是酸洗代码返回的原始
字节
实例的
repr
s。这有点不幸,但也不太坏
repr
用于返回对象的“机器友好”表示形式,通常可以使用
eval
进行反转:

import numpy as np
import pickle

# this part has already happened
orig_obj = np.array([1,2,3])
orig_pickle = pickle.dumps(orig_obj)
saved_str = repr(orig_pickle)     # this was a mistake, but it's already done

# this is what you need to do to get something equivalent to orig_obj back
reconstructed_pickle = eval(saved_str)
reconstructed_obj = pickle.loads(reconstructed_pickle)

# test
if np.all(reconstructed_obj == orig_obj):
    print("It worked!")

必须注意,使用
eval
可能很危险:请注意
eval
可以运行它想要的任何Python代码,因此不要使用不可信的数据调用它。但是,pickle数据也有同样的风险(恶意pickle字符串可以在取消pickle时运行任意代码),因此在这种情况下不会损失太多安全性。我猜在这种情况下,您仍然信任您的数据。

谢谢!这是完美的工作。我不知道eval/exec是用这种语言写的,呵呵。
import numpy as np
import pickle

# this part has already happened
orig_obj = np.array([1,2,3])
orig_pickle = pickle.dumps(orig_obj)
saved_str = repr(orig_pickle)     # this was a mistake, but it's already done

# this is what you need to do to get something equivalent to orig_obj back
reconstructed_pickle = eval(saved_str)
reconstructed_obj = pickle.loads(reconstructed_pickle)

# test
if np.all(reconstructed_obj == orig_obj):
    print("It worked!")