我需要将一个Python3对象pickle成一个字符串,我想从Travis CI构建中的环境变量中取消pickle.问题是,我似乎找不到在Python3中pickle到可移植字符串(unicode)的方法:

import os, pickle    

from my_module import MyPickleableClass


obj = {'cls': MyPickleableClass, 'other_stuf': '(...)'}

pickled = pickle.dumps(obj)

# raises TypeError: str expected, not bytes
os.environ['pickled'] = pickled

# raises UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb (...)
os.environ['pickled'] = pickled.decode('utf-8')

pickle.loads(os.environ['pickled'])

有没有办法将复杂对象(如datetime.datetime)序列化为unicode或Python3中的其他字符串表示形式,我可以将其传输到另一台机器并反序列化?

使现代化

我已经测试了@kindall建议的解决方案,但pickle.dumps(obj, 0).decode()会带来UnicodeDecodeError.尽管如此,base64方法仍然有效,但需要extra decode/encode步.该解决方案对两种Python 都有效.x和Python 3.十、

# encode returns bytes so it needs to be decoded to string
pickled = pickle.loads(codecs.decode(pickled.encode(), 'base64')).decode()

type(pickled)  # <class 'str'>

unpickled = pickle.loads(codecs.decode(pickled.encode(), 'base64'))

推荐答案

pickle.dumps()生成一个bytes对象.期望这些任意字节是有效的UTF-8文本(通过try 将其解码为UTF-8中的字符串而做出的假设)是非常乐观的.如果成功的话,那就是巧合!

一种解决方案是使用完全使用ASCII字符的旧酸洗协议.这仍然是bytes,但由于它是ASCII码,所以可以在没有压力的情况下解码为字符串:

pickled = pickle.dumps(obj, 0).decode()

还可以使用其他一些编码方法将二进制pickle对象编码为文本,例如base64:

import codecs
pickled = codecs.encode(pickle.dumps(obj), "base64").decode()

解码将是:

unpickled = pickle.loads(codecs.decode(pickled.encode(), "base64"))

在协议0中使用pickle似乎会产生比base64编码的二进制pickle更短的字符串(abarnert建议的十六进制编码甚至会比base64更大),但我还没有对其进行严格测试.用你的数据测试一下,看看.

Python-3.x相关问答推荐

Django 5.0.2和django_rest_framework

只有在Chrome尚未打开的情况下,打开Chrome后,PySimpleGUI窗口才会崩溃

确定字符串的长度并提取前15或14个字符

Python3和请求-超文本标记语言:试图抓取一个网站-没有取回真正的超文本标记语言代码

S的两极是什么,相当于大Pandas 的`.ilo‘方法?

数组列的极点成对求和

PyQt5 中耦合滑块和拨号小部件.解决结果不一致的问题

在Pandas中,根据另一列中的重复值将数据分组为一列

python3,将整数转换为字节:对于小整数使用 to_bytes() 有哪些替代方法?

为什么不能用格式字符串 '-' 绘制点?

如何将 WebDriver 传输到导入的测试?

如何统计一个值连续出现的次数?

在 Python 中实现 COM 接口

Python3:是否可以将变量用作函数调用的一部分

安装没有 sudo 权限的 python3 和 pip3

如何查找 tensorflow.python.data.ops.dataset_ops.MapDataset 对象的大小或形状,make_csv_dataset 的输出

Semaphore信号量 Python 的工作原理

无论如何我可以在 Google colaboratory 中下载文件吗?

将字符串拆分为最大长度 X 的片段 - 仅在空格处拆分

如何在 Python 3.2 中退出?