数据序列化

../_images/33467946364_3e59bd376a_k_d.jpg

什么是数据序列化?

数据序列化是指将结构化数据转换成允许以共享或存储的格式,并能恢复成原始结构。在某些情况下,数据序列化的第二个目的是减少数据大小,从而减小对磁盘和带宽的要求。

Flat vs. Nested data

在开始序列化数据之前,确定或决定在数据序列化期间如何结构化数据(扁平或嵌套)是非常重要的。以下示例中显示了两种风格的差异。

扁平风格:

{"Type":"A","field1":"value1","field2":"value2","field3":"value3"}

嵌套风格:

{"A"{"field1":"value1","field2":"value2","field3":"value3"}}

阅读两种风格的更多内容,请见如下讨论:Python mailing list,IETF mailing list andin stackexchange.

序列化文本

简单文件(扁平数据)

如果要序列化的数据位于文件中,并包含扁平数据,则Python提供了两种序列化数据的方法。

repr

Python 中的 repr 方法接收单个对象参数,返回输入的可打印形式:

# 扁平文本作为输入a={"Type":"A","field1":"value1","field2":"value2","field3":"value3"}# 相同的输入可以读取自文件a=open('/tmp/file.py','r')# 返回输入的可打印形式# 输出也能够写入文件print(repr(a))# 使用repr将内容写入文件withopen('/tmp/file.py')asf:f.write(repr(a))

ast.literal_eval

literal_eval 方法安全地解析Python数据类型表达式并求值。其支持的数据类型有:字符串、数字、元组、列表、字典、布尔和None。

withopen('/tmp/file.py','r')asf:inp=ast.literal_eval(f.read())

CSV 文件 (扁平数据)

Python 中的 CSV 模块实现了读取和写入CSV形式的表格数据的类。

读取的简单例子:

# 从文件中读取CSV数据importcsvwithopen('/tmp/file.csv',newline='')asf:reader=csv.reader(f)forrowinreader:print(row)

写入的简单例子:

# 将CSV数据写入文件importcsvwithopen('/temp/file.csv','w',newline='')asf:writer=csv.writer(f)writer.writerows(iterable)

该模块的内容、函数和例子可以在Python 文档中 查阅。

YAML (嵌套数据)

Python 中有许多第三方库用来解析和读取/写入 YAML 文件,例子如下:

# 使用load方法从文件中读取 YAML 内容importyamlwithopen('/tmp/file.yaml','r',newline='')asf:try:print(yaml.load(f))exceptyaml.YAMLErrorasymlexcp:print(ymlexcp)

第三方库的文档可以在PyYAML 文档 中查阅。

JSON 文件 (嵌套数据)

Python 的 JSON 模块可以用来读取和写入 JSON 模块。示例如下:

读取:

# 从文件中读取 JSON 内容importjsonwithopen('/tmp/file.json','r')asf:data=json.load(f)

写入:

# 使用 dump 方法将 JSON 内容写入文件importjsonwithopen('/tmp/file.json','w')asf:json.dump(data,f,sort_keys=True)

XML (嵌套数据)

Python 中 XML 的解析可以使用xml 库。

示例:

# 从文件中读取 XML 内容importxml.etree.ElementTreeasETtree=ET.parse('country_data.xml')root=tree.getroot()

使用xml.domxml.sax 包的更多文档可以在Python XML 库文档 中找到。

二进制

NumPy Array (扁平数据)

Python 的 NumPy 数组可以将数据序列化成字节形式,或从字节形式的数据反序列化。

示例:

importNumPyasnp# 将 NumPy 数组转换为字节形式byte_output=np.array([[1,2,3],[4,5,6],[7,8,9]]).tobytes()# 将字节形式转换回 NumPy 数组array_format=np.frombuffer(byte_output)

Pickle (扁平数据)

Python原生的数据序列化模块称为Pickle

示例:

importpickle# 示例字典grades={'Alice':89,'Bob':72,'Charles':87}# 使用 dumps 将对象转换为序列化字符串serial_grades=pickle.dumps(grades)# 使用 loads 反序列化为对象received_grades=pickle.loads(serial_grades)

Protobuf

如果您正在寻找支持多种语言的序列化模块,那么Google的Protobuf 库就是一个选择。