Python 数据持久化
Python data persistence
每当 Python 对象需要存储或通过网络发送时,它首先被序列化。我猜是因为存储和网络传输都是基于比特的。我有一个愚蠢的问题,它更像是计算机科学基础问题而不是 python 问题。 python 对象在缓存中时采用哪种格式?他们不应该将自己表示为位吗?如果是这样,为什么不直接使用这些位来存储或发送对象,为什么还要麻烦序列化?
位表示法
同一个对象在不同机器上的位可以有不同的表示:
- 考虑字节顺序 (byte-order)
- 和架构(32位,64位)
因此,在发送方机器上 位 中的对象表示在接收方机器上可能没有任何意义(或者更糟糕的可能意味着其他东西)。
拿一个简单的整数1025来说明问题:
- 在 Big Endian 机器上 Bits 表示是:
- 二进制:
00000000 00000000 00000100 00000001
- 十六进制:
0x00000401
- 在 Little Endian 机器上:
- 二进制:
00000001 00000100 00000000 00000000
- 十六进制
0x01040000
这就是为什么要相互理解,2 台机器必须就约定、协议达成一致。对于 IP 协议,惯例是使用网络字节顺序 (big-endian) 例如。
更多关于字节顺序的信息in this question
序列化(和反序列化)
我们不能直接在网络上发送底层 位表示 的对象,原因如上所述,但不仅如此。
一个对象可以在内部通过指针(第二个对象的 in-memory 地址)引用另一个对象。这个地址又是 platform-dependent.
Python 使用称为 pickling 的序列化算法解决了这个问题,该算法将对象层次结构转换为 byte-stream。这个byte-stream,当通过网络发送时,仍然是platform-dependent,这就是为什么两端需要一个协议来相互理解的原因。
I/O is achieving interoperability的关键点,例如您通过网络发送的 JSON 可能需要通过 HTTP 协议传输,然后由 JavaScript 解析。并且您存储在磁盘上的数据可能需要在您下次 运行 Python 时可读(不同 运行 时间环境,内存分配,...)。
但是对于代码执行,你通常希望尽可能达到更高的performance than what would be possible using interoperable formats, e.g. using memory location addresses to access object methods, dict items, ... Or optimizing for processor cache。
有关 python 的具体实施方式的详细信息,您可以查看 interpreter implementations 之一。
每当 Python 对象需要存储或通过网络发送时,它首先被序列化。我猜是因为存储和网络传输都是基于比特的。我有一个愚蠢的问题,它更像是计算机科学基础问题而不是 python 问题。 python 对象在缓存中时采用哪种格式?他们不应该将自己表示为位吗?如果是这样,为什么不直接使用这些位来存储或发送对象,为什么还要麻烦序列化?
位表示法
同一个对象在不同机器上的位可以有不同的表示:
- 考虑字节顺序 (byte-order)
- 和架构(32位,64位)
因此,在发送方机器上 位 中的对象表示在接收方机器上可能没有任何意义(或者更糟糕的可能意味着其他东西)。
拿一个简单的整数1025来说明问题:
- 在 Big Endian 机器上 Bits 表示是:
- 二进制:
00000000 00000000 00000100 00000001
- 十六进制:
0x00000401
- 二进制:
- 在 Little Endian 机器上:
- 二进制:
00000001 00000100 00000000 00000000
- 十六进制
0x01040000
- 二进制:
这就是为什么要相互理解,2 台机器必须就约定、协议达成一致。对于 IP 协议,惯例是使用网络字节顺序 (big-endian) 例如。
更多关于字节顺序的信息in this question
序列化(和反序列化)
我们不能直接在网络上发送底层 位表示 的对象,原因如上所述,但不仅如此。
一个对象可以在内部通过指针(第二个对象的 in-memory 地址)引用另一个对象。这个地址又是 platform-dependent.
Python 使用称为 pickling 的序列化算法解决了这个问题,该算法将对象层次结构转换为 byte-stream。这个byte-stream,当通过网络发送时,仍然是platform-dependent,这就是为什么两端需要一个协议来相互理解的原因。
I/O is achieving interoperability的关键点,例如您通过网络发送的 JSON 可能需要通过 HTTP 协议传输,然后由 JavaScript 解析。并且您存储在磁盘上的数据可能需要在您下次 运行 Python 时可读(不同 运行 时间环境,内存分配,...)。
但是对于代码执行,你通常希望尽可能达到更高的performance than what would be possible using interoperable formats, e.g. using memory location addresses to access object methods, dict items, ... Or optimizing for processor cache。
有关 python 的具体实施方式的详细信息,您可以查看 interpreter implementations 之一。