问题的提出
给出一个包含列表 和其他数据结构的Python 字典。你想把字典存储在一个文件中,或者以一种更有效的形式在网络上发送它。
如何将 Python dictionary 序列化为一个字符串,然后将字符串反序列化为一个 dictionary 数据结构?
这里有一个粗略的例子,说明你想做什么。
Serialization Example
所以,让我们马上深入了解最Pythonic的解决方案吧!
用 Pickle 序列化和反序列化一个 dict
要序列化一个给定的字典d ,只需用import pickle 导入pickle 模块,并将pickle.dumps(d) 的结果分配给一个变量。这个变量将持有一个序列化的二进制字符串,你可以用它来把字典存储在你的计算机上或通过网络发送。
import pickle
d = {'Hello': [1, 2, 3], 42: 'World'}
serialized_d = pickle.dumps(d)
如果你打印 这个字符串变量,你会得到一个代表序列化字典的不可读的二进制字符串输出。
print(serialized_d)
# b'\x80\x04\x95!\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x05Hello\x94]\x94(K\x01K\x02K\x03eK*\x8c\x05World\x94u.'
要对pickle.dumps() 创建的二进制字符串进行反序列化,并从中创建一个新的 dictionary 对象,请使用pickle.loads() 函数,并将序列化的二进制字符串表示法传给它。输出是一个新的 dictionary 对象,它与原来的未序列化的 dictionary 不同。
deserialized_d = pickle.loads(serialized_d)
print(deserialized_d)
# {'Hello': [1, 2, 3], 42: 'World'}
总而言之,这是对 Python 字典进行序列化和反序列化的最 Pythonic 的方法。
import pickle
d = {'Hello': [1, 2, 3], 42: 'World'}
# Serialize Dict
serialized_d = pickle.dumps(d)
print(serialized_d)
# b'\x80\x04\x95!\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x05Hello\x94]\x94(K\x01K\x02K\x03eK*\x8c\x05World\x94u.'
# Deserialize Dict
deserialized_d = pickle.loads(serialized_d)
print(deserialized_d)
# {'Hello': [1, 2, 3], 42: 'World'}
你可以确认原始的 dictionary 和反序列化的 dictionary 是副本,但是没有使用is 操作符指向同一个对象。
print(d is deserialized_d)
# False
但是也可以考虑一个简单的无库替代方法!
序列化和反序列化一个 dict - 快速和肮脏的无库方法
要以人类可读的方式,在不依赖外部的情况下序列化Python dict,只需使用内置函数将字符串转换成一个字典即可 [str()](https://blog.finxter.com/python-str-function/ "Python str() Function").要将其反序列化,将 dict 的字符串表示法传入内置的 [eval()](https://blog.finxter.com/python-eval/ "Python eval()")函数,该函数将返回一个新的字典对象,它是原始字典的副本。
d = {'Hello': [1, 2, 3], 42: 'World'}
# Serialize Dict
serialized_d = str(d)
print(serialized_d)
# Deserialize Dict
deserialized_d = eval(serialized_d)
print(deserialized_d)
这种方法的优点是简单,不需要库。序列化的 dictionary 也是人类可读的。然而,与前面的方法相比,它的效率很低,因为序列化的字符串带有很多不必要的开销,这些开销可以通过pickle 进行优化。
Python [eval(s)](https://blog.finxter.com/python-eval/ "https://blog.finxter.com/python-eval/")是一个内置函数 ,它将字符串参数s 解析为一个 Python 表达式,运行它,并返回表达式的结果。你可以在这里观看我关于这个特殊函数的解释视频。