Python 序列化
Apache Fory™ Python
Apache Fory™ 是一个极速的多语言序列化框架,基于 JIT 编译和零拷贝技术,在保持易用性和安全性的同时提供超高性能。
pyfory 提供了 Apache Fory™ 的 Python 实现,同时支持高性能对 象序列化和用于数据处理任务的高级行格式能力。
🚀 核心特性
🔧 灵活的序列化模式
- Python 原生模式:完全兼容 Python,可作为 pickle/cloudpickle 的直接替代品
- 跨语言模式:针对多语言数据交换优化
- 行格式:用于分析工作负载的零拷贝行格式
🎯 多样的序列化功能
- 共享/循环引用支持:在 Python 原生模式和跨语言模式中支持复杂对象图
- 多态支持:支持自定义类型的自动类型分发
- Schema 演化:在跨语言模式下使用 dataclass 时支持向后/向前兼容
- 带外缓冲区支持:支持大型数据结构(如 NumPy 数组和 Pandas DataFrame)的零拷贝序列化,兼容 pickle protocol 5
⚡ 极速性能
- 相比其他序列化框架具有极快的性能
- 运行时代码生成和 Cython 加速的核心实现,获得最佳性能
📦 紧凑的数据大小
- 紧凑的对象图协议,空间开销极小——相比 pickle/cloudpickle 最多减少 3 倍大小
- 元数据打包和共享,最小化类型向前/向后兼容的空间开销
🛡️ 安全性
- 严格模式通过类型注册和检查防止反序列化不受信任的类型
- 引用跟踪安全处理循环引用
📦 安装
基础安装
使用 pip 安装 pyfory:
pip install pyfory
可选依赖
# 安装行格式支持(需要 Apache Arrow)
pip install pyfory[format]
# 从源码安装用于开发
git clone https://github.com/apache/fory.git
cd fory/python
pip install -e ".[dev,format]"
环境要求
- Python:3.8 或更高版本
- 操作系统:Linux、macOS、Windows
🐍 Python 原生序列化
pyfory 提供了 Python 原生序列化模式,提供与 pickle/cloudpickle 相同的功能,但具有显著更好的性能、更小的数据大小和增强的安全特性。
二进制协议和 API 与 Fory 的 xlang 模式类似,但 Python 原生模式可以序列化任何 Python 对象——包括全局函数、局部函数、lambda 表达式、局部类以及使用 __getstate__/__reduce__/__reduce_ex__ 自定义序列化的类型,这些在 xlang 模式中是不允许的。
要使用 Python 原生模式,请创建 xlang=False 的 Fory。此模式针对纯 Python 应用程序优化:
import pyfory
fory = pyfory.Fory(xlang=False, ref=False, strict=True)
基础对象序列化
使用简单的 API 序列化和反序列化 Python 对象。此示例展示了序列化包含混合类型的字典:
import pyfory
# 创建 Fory 实例
fory = pyfory.Fory(xlang=True)
# 序列化任何 Python 对象
data = fory.dumps({"name": "Alice", "age": 30, "scores": [95, 87, 92]})
# 反序列化回 Python 对象
obj = fory.loads(data)
print(obj) # {'name': 'Alice', 'age': 30, 'scores': [95, 87, 92]}
注意:dumps()/loads() 是 serialize()/deserialize() 的别名。两组 API 完全相同,使用您觉得更直观的即可。
自定义类序列化
Fory 自动处理 dataclass 和自定义类型。注册您的类一次,然后无缝序列化实例:
import pyfory
from dataclasses import dataclass
from typing import List, Dict
@dataclass
class Person:
name: str
age: int
scores: List[int]
metadata: Dict[str, str]
# Python 模式 - 支持所有 Python 类型,包括 dataclass
fory = pyfory.Fory(xlang=False, ref=True)
fory.register(Person)
person = Person("Bob", 25, [88, 92, 85], {"team": "engineering"})
data = fory.serialize(person)
result = fory.deserialize(data)
print(result) # Person(name='Bob', age=25, ...)
Pickle/Cloudpickle 的直接替代品
pyfory 可以使用以下配置序列化任何 Python 对象:
- 循环引用:设置
ref=True启用引用跟踪 - 函数/类:设置
strict=False允许反序列化动态类型
⚠️ 安全警告:当 strict=False 时,Fory 将反序列化任意类型,如果数据来自不可信来源,这可能带来安全风险。仅在您完全信任数据源的受控环境中使用 strict=False。如果确实需要使用 strict=False,请在创建 fory 时使用 policy=your_policy 配置 DeserializationPolicy 来控制反序列化行为。
常见用法
序列化常见的 Python 对象,包括字典、列表和自定义类,无需任何注册:
import pyfory
# 创建 Fory 实例
fory = pyfory.Fory(xlang=False, ref=True, strict=False)
# 序列化常见的 Python 对象
data = fory.dumps({"name": "Alice", "age": 30, "scores": [95, 87, 92]})
print(fory.loads(data))
# 序列化自定义对象
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
person = Person("Bob", 25)
data = fory.dumps(person)
print(fory.loads(data)) # Person(name='Bob', age=25)