编程全栈开发工程师

什么是Python中对象的序列化和反序列化?在何时使用pickle,何时使用json,它们的原则差异是什么?

用 Hintsage AI 助手通过面试

回答。

序列化是将对象转换为字节流(或字符串)的过程,以便保存或通过网络传输,而反序列化是逆过程。

在Python中,历史上主要的问题是标准化在不同应用程序和语言之间交换复杂数据结构。因此,标准库中出现了不同的模块:首先是pickle用于序列化任何Python对象,后来是json用于与外部系统的通用交换。

问题:pickle存储的是Python特定数据,不安全(加载时可能执行任意代码)并且与其他语言不兼容,而json仅限于简单类型(dict、list、str、int、float、bool和None),但更安全,广泛用于不同技术之间的交流。

解决方案:仅在受信任的数据之间使用pickle;使用json与外部服务、网页开发和传输人类可读数据的结构进行交换。

示例代码:

import pickle import json data = {'a': [1, 2, 3], 'b': True} # 使用pickle序列化 pickled = pickle.dumps(data) # 字节 unpickled = pickle.loads(pickled) print(unpickled) # 使用json序列化 jsoned = json.dumps(data) # 字符串 unjsoned = json.loads(jsoned) print(unjsoned)

关键特点:

  • pickle序列化(几乎)任何Python对象,但是有危险并且不通用。
  • json仅序列化基本类型,但安全且跨语言。
  • 始终考虑安全性和应用领域。

误导性问题。

可以通过pickle向外部系统的HTTP API返回吗?

不可以!pickle不是语言间数据交换的标准,并且极其不安全:从pickle加载可能执行外部代码。json在外部交互中更好。

可以在json中序列化函数、类或lambda函数吗?

不可以。json仅处理原始类型;标准json和大多数解析器都不支持序列化函数和类。

pickle能序列化具有循环引用的对象吗?

可以,pickle会自动处理大多数循环引用,甚至递归结构。而对于json,这通常会导致致命错误。

常见错误与反模式

  • 从不可靠来源序列化用户数据使用pickle — 是一种关键漏洞。
  • 尝试通过json序列化非标准类型(例如,datetime)而不进行修改 — 会导致错误。
  • 在服务器上存储pickle文件而不进行安全控制。

生活中的实例

负面案例:将pickle对象传递给客户端应用程序以交换数据。
优点:实现简单,保留所有Python类型。
缺点:极其危险,无法与其他语言交互。

正面案例:通过json发送数据,使用编码器转换非标准类型。
优点:安全性、兼容性、灵活性。
缺点:对支持的类型有限制,有时需要自定义编码器/解码器。