# 12.4. `marshal` — Python 内部对象序列化

此模块包含可以用二进制格式读取和写入Python值的函数。该格式特定于Python，但不依赖于机器架构问题（例如，你可以将Python值写入PC上的文件，将文件传输到Sun，然后读回它）。格式的细节有意没写成文档；它可能会在Python版本之间变化（虽然很少这样做）。[1]

这不是一个通用的“持久性”模块。对于通过RPC调用的通用的 Python 对象的持久性和传输，请参见模块`pickle`和`shelve`。`marshal`模块主要用于支持读取和写入Python模块的`.pyc`文件的“伪编译”代码。因此，Python维护者保留在需要时以向后不兼容的方式修改元组格式的权利。如果你要序列化和反序列化Python对象，使用`pickle`模块 - 性能是可比的，版本独立性得到保证，pickle支持比marshal更宽的对象范围。

警告

`marshal`模块并非旨在防止错误或恶意构造的数据。切勿对从不受信任或未经身份验证的来源接收的数据进行解组。

不是所有的Python对象类型都支持；一般来说，只有其值独立于Python的特定调用的对象才能被该模块写入和读取。支持以下类型：布尔，整数，浮点数，复数，字符串，字节，字节数，元组，列表，集合，冻结，字典和代码对象，其中应当理解元组，列表，集，并且只支持字典，只要其中包含的值本身被支持。单例`None`，`Ellipsis`和`StopIteration`也可以编组和取消组合。对于版本低于3的格式，不能写入递归列表，集合和字典（见下文）。

有一些函数读/写文件以及对字符串操作的函数。

模块定义了这些功能：

`marshal.``dump`(value, file[, version])

  在打开的文件上写入值。该值必须是受支持的类型。文件必须是打开的文件对象，例如`sys.stdout`或由`open()`或`os.popen()`返回。它必须以二进制模式打开（`'wb'`或`'w+b'`）。

  如果值具有（或包含具有）不受支持类型的对象，则会引发`ValueError`异常 - 但垃圾数据也将写入文件。该对象将不会被`load()`正确读取。

  版本参数表示`dump`应使用的数据格式（见下文）。

`marshal.``load`(file)

  从打开的文件中读取一个值并返回。如果没有读取有效值（例如，因为数据具有不同的Python版本不兼容的封送格式），引发`EOFError`，`ValueError`或`TypeError`。该文件必须是以二进制模式打开的打开文件对象（`'rb'`或`'r+b'`）。

  注意

  如果包含不支持类型的对象与`dump()`编组，`load()`将替换`None`

`marshal.``dumps`(value[, version])

  返回`dump（value， 文件）`将写入文件的字符串。该值必须是受支持的类型。如果值具有（或包含具有）不受支持类型的对象，则引发`ValueError`异常。

  版本参数表示`dumps`应使用的数据格式（见下文）。

`marshal.``loads`(string)

  将字符串转换为值。如果没有找到有效值，引发`EOFError`，`ValueError`或`TypeError`。字符串中的额外字符将被忽略。

此外，还定义了以下常数：

`marshal.``version`

  表示模块使用的格式。版本0是历史格式，版本1共享内部字符串，版本2使用二进制格式的浮点数。版本3增加了对对象实例化和递归的支持。当前版本为4。

脚注

[1] | 这个模块的名字来源于Modula-3的设计者使用的一些术语，他们使用术语“编组”以自包含形式传送数据。严格来说，“to marshal”意味着将一些数据从内部转换为外部形式（在实例的RPC缓冲区中），“反编译”用于反向过程。