3

每当需要通过网络存储或发送 Python 对象时,它首先被序列化。我猜原因是存储和网络传输都是基于位的。我有一个愚蠢的问题,这更像是一个计算机科学基础问题,而不是一个 Python 问题。python 对象在缓存中时采用什么样的格式?他们不应该将自己表示为比特吗?如果是这种情况,为什么不直接使用这些位来存储或发送对象,为什么还要麻烦序列化呢?

4

2 回答 2

3

位表示

同一个对象在不同机器上的Bits中可以有不同的表示:

  • 考虑字节顺序(字节顺序)
  • 架构(32 位,64 位)

因此,当在接收方接收到时,发送方机器上的Bits中的对象表示可能没有任何意义,(或更糟糕的可能意味着其他东西)。

以一个简单的整数 1025 作为问题的说明:

  • 在 Big Endian 机器上,Bits表示为:
    • 二进制:00000000 00000000 00000100 00000001
    • 十六进制:0x00000401
  • 在 Little Endian 机器上:
    • 二进制:00000001 00000100 00000000 00000000
    • 十六进制0x01040000

这就是为什么要相互理解,两台机器必须就约定、协议达成一致。对于 IP 协议,约定是使用例如网络字节顺序(大端)。

更多关于这个问题的字节顺序

序列化(和反序列化)

由于前面描述的原因,我们不能直接在网络上发送对象底层位表示,但不仅如此。

一个对象可以通过指针(第二个对象的内存地址)在内部引用另一个对象。此地址再次依赖于平台

Python 使用一种称为pickling的序列化算法来解决这个问题,该算法将对象层次结构转换为字节流。当通过网络发送时,这个字节流仍然依赖于平台,这就是为什么两端需要一个协议来相互理解。

Pickle 模块文档

于 2016-01-17T16:34:54.767 回答
1

I/O的关键点是实现互操作性,例如,您通过网络发送的 JSON 可能需要通过 HTTP 协议传输,然后由 JavaScript 解析。并且您存储在磁盘上的数据可能需要在下次运行 Python 时可读(不同的运行时环境、内存分配……)。

但是对于代码执行,您通常希望获得比使用可互操作格式可能实现的性能更高的性能,例如使用内存位置地址来访问对象方法、dict 项……或尽可能优化处理器缓存。

有关 python 是如何实现的详细信息,您可以查看其中一个解释器实现

于 2016-01-17T17:22:47.473 回答