内部 Python 对象序列化 (marshal)

pythonprogrammingserver side programming更新于 2023/12/13 6:29:00

尽管 Python 标准库中的 marshal 模块提供了对象序列化功能(类似于 pickle 模块),但它对于通用数据持久性或通过套接字等传输 Python 对象并没有太大用处。此模块主要由 Python 本身使用,以支持对编译版本的 Python 模块 (.pyc 文件) 进行读/写操作。marshal 模块使用的数据格式在各个 Python 版本之间不兼容(甚至 subversion 也不兼容)。这就是为什么一个版本的编译 Python 脚本 (.pyc 文件) 很可能不会在另一个版本上执行的原因。因此,marshal 模块用于 Python 的内部对象序列化。

与 pickle 模块一样,marshal 模块还定义了 load() 和 dump() 函数,用于从文件读取和将编组对象写入文件。此外,loads() 和 dumps() 函数处理已编组对象的字符串表示形式。

dumps() − 通过编组 Python 对象返回一个字节类对象。仅支持编组标准数据类型的对象。不支持的类型会引发 ValueError 异常。

loads() − 此函数将字节类对象转换为相应的 Python 对象。如果转换未产生有效的 Python 对象,则可能会引发 ValueError 或 TypeError。

以下代码显示了使用 dumps() 编组的 Python 字典对象。字节表示通过 loads() 函数转换回字典。

import marshal
person = {"name":"xyz", "age":22, "marks":[45,56,78]}
data = marshal.dumps(person)
obj = marshal.loads(data)
print (obj)

dump() − 此函数将支持的 Python 对象的字节表示写入文件。文件本身是具有写权限的二进制文件

load() − 此函数从二进制文件读取字节数据并将其转换为 Python 对象。

如上所述,marshal 模块用于处理 .pyc 文件。以下示例演示了如何使用 dump() 和 load() 函数来处理 Python 的代码对象,这些代码对象用于存储预编译的 Python 模块。

代码使用内置的 compile() 函数从嵌入 Python 指令的源字符串构建代码对象。

compile(source, file, mode)

file 参数应该是读取代码的文件。如果不是从文件中读取的,则传递任意字符串。

如果源包含语句序列,则 mode 参数为 ‘exec’,如果只有一个表达式,则为 ‘eval’,否则为 ‘single’如果它包含单个交互式语句。

然后使用 dump() 函数将编译代码对象存储在 .pyc 文件中

import marshal
script = """
a = 10
b = 20
print ('addition = ',a+b)
"""
code = compile(script, "script", "exec")
f = open("a.pyc","wb")
marshal.dump(code, f)
f.close()

要从 .pyc 文件中反序列化对象,请使用 load() 函数。由于它返回一个代码对象,因此可以使用另一个内置函数 exec() 来运行它。

import marshal
f = open("a.pyc","rb")
data = marshal.load(f)
exec (data)

输出将是嵌入在源字符串中的代码块的结果

addition = 30

相关文章