我有一个更复杂的对象,它也包含一些继承等。我希望能够对其进行腌制/解开并将其另存为文件。但是它只有在内存中时才起作用。当我将其读取为文件时,无法正确将其转换回去。
只要我在python(Django)应用程序中使用它就可以了:
myPickle=pickle.dumps(reallyComplicatedObject, 0).decode()
...
myObject = pickle.loads(myPickle.encode())
现在我将其保存以备将来使用(我不得不假装它是一个文件,因为Django不允许我将字符串另存为文件):
fs = FileSystemStorage()
notAFile = io.StringIO(pickle.dumps(reallyComplicatedObject, 0).decode())
filename = fs.save(filename, notAFile)
return fs.url(filename)
这与预期的一样。我有一个看起来对我来说或多或少是二进制文件 现在,请注意:
storage_class = get_storage_class(settings.STATICFILES_STORAGE)
complicatedPickle = None
with storage_class().open('TestFiles/Pickles/thatOneObject') as picklereads:
complicatedPickle = picklereads.read()
pick = pickle.loads(complicatedPickle)
当我输出complicatedPickle
时,我得到了一个长字符串,它看起来对我来说是二进制的。在这里,我已经很奇怪了,正如我期望的那样,它是一个字符串-
(Pdb) type(complicatedPickle)
<class 'bytes'>
pick
是一个字符串,对其进行编码只会使其再次变为二进制:
(Pdb) type(pick)
<class 'str'>
(Pdb) type(pick.encode())
<class 'bytes'>
我已尝试在此解决方案中使用ast
,例如:https://stackoverflow.com/a/52891113/2516892
nopick = pickle.loads(ast.literal_eval(complicatedPickle))
但是出问题了,因为这只是输出对象。之后,我没有nopick
变量。
同一页面上的下一个解决方案也没有帮助:
(Pdb) unpick=pickle.loads(bytes(complicatedPickle))
(Pdb) type(unpick)
<class 'str'>
(Pdb) unpick=pickle.loads(bytes(complicatedPickle, "latin1"))
*** TypeError: encoding without a string argument
(Pdb) unpick=pickle.load(bytes(complicatedPickle, "latin1"))
*** TypeError: encoding without a string argument
我现在被困住了。我的转换中已经有错误吗?还是我应该再次使其物化?还是该问题可能与Django有关,因为我没有使用常规的open
,而是使用storage_class
?
答案 0 :(得分:0)
这里有两个主要问题:
FileSystemStorage
不能写二进制文件,StringIO
不能假装String是二进制的(也许可以,但是并不是很简单)我需要将保存功能抛弃为非Django风格:
import os
sfilename = os.path.join(settings.STATIC_ROOT,
"TestFiles/Pickles/"+filename)
with open(sfilename, 'wb') as f:
f.write(pickle.dumps(obj, 0)) #also not decoding it any more
return sfilename
检索更为简单:
with storage_class().open('TestFiles/Pickles/'+filename, mode='rb') as pickle:
complicatedObject = pickle.load(pickle)
就是这样