快速、正确的Python JSON库,支持dataclasses、datetimes和numpy
项目描述
orjson
orjson 是一个快速、正确的Python JSON库。它在性能基准测试中被证明是Python中最快的JSON库,并且比标准json库或其他第三方库更准确。它可以原生序列化dataclass、datetime、numpy和UUID实例。
与其它Python JSON库相比,其特性和缺点
- 序列化 dataclass实例的速度比其他库快40-50倍
- 将 datetime、date和time实例序列化为RFC 3339格式,例如,“1970-01-01T00:00:00+00:00”
- 以0.3倍其他库的内存使用率,将 numpy.ndarray实例序列化速度快4-12倍
- 比标准库快10-20倍进行美化打印
- 序列化为bytes而不是str,即不是直接替换
- 不转义Unicode为ASCII序列化str,例如,“好”而不是“\\u597d”
- 序列化float比其他库快10倍,反序列化比其他库快一倍
- 原生序列化str、int、list和dict的子类,需要使用default指定如何序列化其他类型
- 使用default钩子序列化任意类型
- 具有严格的UTF-8兼容性,比标准库更正确
- 严格遵循JSON规范,不支持Nan/Infinity/-Infinity
- 在53位整数上具有严格的JSON兼容性,默认支持64位
- 不提供从/向文件对象读写操作的load()或dump()函数
orjson支持CPython 3.8、3.9、3.10、3.11、3.12和3.13。它为Linux提供amd64/x86_64、aarch64/armv8、arm7、POWER/ppc64le和s390x的wheels,为macOS提供amd64和aarch64的wheels,为Windows提供amd64和i686/x86的wheels。orjson不支持也不将支持PyPy。orjson不支持也不将支持PEP 554子解释器。发布遵循语义版本控制,不通过opt-in标志序列化新的对象类型被视为破坏性变更。
orjson同时受Apache 2.0和MIT许可协议的约束。仓库和问题跟踪器位于github.com/ijl/orjson,补丁可以提交到那里。仓库中提供了一个变更日志。
用法
安装
要从PyPI安装wheel,请参阅
pip install --upgrade "pip>=20.3" # manylinux_x_y, universal2 wheel support
pip install --upgrade orjson
要构建wheel,请参阅打包。
快速入门
这是一个序列化示例,其中指定了选项,并进行了反序列化
>>> import orjson, datetime, numpy
>>> data = {
    "type": "job",
    "created_at": datetime.datetime(1970, 1, 1),
    "status": "🆗",
    "payload": numpy.array([[1, 2], [3, 4]]),
}
>>> orjson.dumps(data, option=orjson.OPT_NAIVE_UTC | orjson.OPT_SERIALIZE_NUMPY)
b'{"type":"job","created_at":"1970-01-01T00:00:00+00:00","status":"\xf0\x9f\x86\x97","payload":[[1,2],[3,4]]}'
>>> orjson.loads(_)
{'type': 'job', 'created_at': '1970-01-01T00:00:00+00:00', 'status': '🆗', 'payload': [[1, 2], [3, 4]]}
迁移
orjson版本3比版本2序列化更多类型。现在序列化了str、int、dict和list的子类。这比标准库更快,更相似。可以通过orjson.OPT_PASSTHROUGH_SUBCLASS禁用。默认情况下,dataclasses.dataclass实例会被序列化,并且在默认函数中不能自定义,除非指定了option=orjson.OPT_PASSTHROUGH_DATACLASS。默认情况下,uuid.UUID实例会被序列化。对于现在被序列化的任何类型,可以在default函数中移除其实现和启用它们的选项,但不需要这么做。反序列化没有变化。
要从标准库迁移,最大的不同是orjson.dumps返回bytes,而json.dumps返回一个str。使用非str键的dict对象应指定option=orjson.OPT_NON_STR_KEYS。sort_keys被option=orjson.OPT_SORT_KEYS替换。indent被option=orjson.OPT_INDENT_2替换,其他级别的缩进不受支持。
序列化
def dumps(
    __obj: Any,
    default: Optional[Callable[[Any], Any]] = ...,
    option: Optional[int] = ...,
) -> bytes: ...
dumps()将Python对象序列化为JSON。
它原生序列化str、dict、list、tuple、int、float、bool、None、dataclasses.dataclass、typing.TypedDict、datetime.datetime、datetime.date、datetime.time、uuid.UUID、numpy.ndarray和orjson.Fragment实例。它通过default支持任意类型。它序列化str、int、dict、list、dataclasses.dataclass和enum.Enum的子类。为了避免序列化子类,指定选项orjson.OPT_PASSTHROUGH_SUBCLASS。
输出是一个包含UTF-8的bytes对象。
在调用期间,全局解释器锁(GIL)被持有。
在不受支持的类型上引发JSONEncodeError。此异常消息描述了包含错误消息类型不是可JSON序列化的:...的无效对象。要修复此问题,请指定默认值。
如果字符串包含无效的UTF-8,则引发JSONEncodeError。
默认情况下,它会在超过64位或使用OPT_STRICT_INTEGER时超过53位的整数上引发JSONEncodeError。
如果字典的键类型不是str,除非指定了OPT_NON_STR_KEYS,否则将引发JSONEncodeError。
如果default的输出递归到default处理超过254层,则引发JSONEncodeError。
在循环引用上引发JSONEncodeError。
如果datetime对象上的tzinfo不受支持,则引发JSONEncodeError。
JSONEncodeError是TypeError的子类。这是为了与标准库兼容。
如果失败是由default中的异常引起的,则JSONEncodeError将原始异常作为__cause__链。
默认
要序列化子类或任意类型,指定default为返回支持类型的可调用对象。default可以是函数、lambda或可调用类实例。要指定类型未由default处理,引发异常,例如TypeError。
>>> import orjson, decimal
>>>
def default(obj):
    if isinstance(obj, decimal.Decimal):
        return str(obj)
    raise TypeError
>>> orjson.dumps(decimal.Decimal("0.0842389659712649442845"))
JSONEncodeError: Type is not JSON serializable: decimal.Decimal
>>> orjson.dumps(decimal.Decimal("0.0842389659712649442845"), default=default)
b'"0.0842389659712649442845"'
>>> orjson.dumps({1, 2}, default=default)
orjson.JSONEncodeError: Type is not JSON serializable: set
default可调用对象可以返回一个对象,该对象本身必须由default处理,最多254次,然后引发异常。
如果类型无法处理,default必须引发异常。否则,Python将隐式返回None,这对于调用者看起来是一个合法的值,并且会被序列化。
>>> import orjson, json, rapidjson
>>>
def default(obj):
    if isinstance(obj, decimal.Decimal):
        return str(obj)
>>> orjson.dumps({"set":{1, 2}}, default=default)
b'{"set":null}'
>>> json.dumps({"set":{1, 2}}, default=default)
'{"set":null}'
>>> rapidjson.dumps({"set":{1, 2}}, default=default)
'{"set":null}'
选项
要修改数据序列化方式,指定option。每个option是orjson中的整数常量。要指定多个选项,将它们掩码在一起,例如:option=orjson.OPT_STRICT_INTEGER | orjson.OPT_NAIVE_UTC。
OPT_APPEND_NEWLINE
将\n追加到输出。这是一个方便的优化,用于dumps(...) + "\n"的模式。bytes对象是不可变的,此模式会复制原始内容。
>>> import orjson
>>> orjson.dumps([])
b"[]"
>>> orjson.dumps([], option=orjson.OPT_APPEND_NEWLINE)
b"[]\n"
OPT_INDENT_2
使用两个空格的缩进格式化输出。这相当于标准库中的indent=2。格式化打印较慢,输出较大。orjson是在格式化打印方面速度最快的库,比标准库慢得少得多。此选项与所有其他选项兼容。
>>> import orjson
>>> orjson.dumps({"a": "b", "c": {"d": True}, "e": [1, 2]})
b'{"a":"b","c":{"d":true},"e":[1,2]}'
>>> orjson.dumps(
    {"a": "b", "c": {"d": True}, "e": [1, 2]},
    option=orjson.OPT_INDENT_2
)
b'{\n  "a": "b",\n  "c": {\n    "d": true\n  },\n  "e": [\n    1,\n    2\n  ]\n}'
如果显示,缩进和换行符将看起来像这样
{
  "a": "b",
  "c": {
    "d": true
  },
  "e": [
    1,
    2
  ]
}
这衡量了将github.json固定序列化为紧凑型(52KiB)或格式化型(64KiB)
| 库 | 紧凑型(ms) | 格式化型(ms) | 与orjson相比 | 
|---|---|---|---|
| orjson | 0.03 | 0.04 | 1 | 
| ujson | 0.18 | 0.19 | 4.6 | 
| rapidjson | 0.1 | 0.12 | 2.9 | 
| simplejson | 0.25 | 0.89 | 21.4 | 
| json | 0.18 | 0.71 | 17 | 
这衡量了将citm_catalog.json固定序列化为紧凑型(489KiB)或格式化型(1.1MiB),这更像是最坏的情况,因为嵌套和换行符的数量较多
| 库 | 紧凑型(ms) | 格式化型(ms) | 与orjson相比 | 
|---|---|---|---|
| orjson | 0.59 | 0.71 | 1 | 
| ujson | 2.9 | 3.59 | 5 | 
| rapidjson | 1.81 | 2.8 | 3.9 | 
| simplejson | 10.43 | 42.13 | 59.1 | 
| json | 4.16 | 33.42 | 46.9 | 
这可以使用pyindent脚本来重现。
OPT_NAIVE_UTC
将没有tzinfo的datetime.datetime对象序列化为UTC。这不会影响设置了tzinfo的datetime.datetime对象。
>>> import orjson, datetime
>>> orjson.dumps(
        datetime.datetime(1970, 1, 1, 0, 0, 0),
    )
b'"1970-01-01T00:00:00"'
>>> orjson.dumps(
        datetime.datetime(1970, 1, 1, 0, 0, 0),
        option=orjson.OPT_NAIVE_UTC,
    )
b'"1970-01-01T00:00:00+00:00"'
OPT_NON_STR_KEYS
序列化除str类型以外的dict键。这允许dict键可以是以下类型之一:str、int、float、bool、None、datetime.datetime、datetime.date、datetime.time、enum.Enum和uuid.UUID。相比之下,标准库默认序列化str、int、float、bool或None。orjson的基准测试表明,在序列化非str键方面,orjson比其他库更快。对于str键,此选项比默认选项慢。
>>> import orjson, datetime, uuid
>>> orjson.dumps(
        {uuid.UUID("7202d115-7ff3-4c81-a7c1-2a1f067b1ece"): [1, 2, 3]},
        option=orjson.OPT_NON_STR_KEYS,
    )
b'{"7202d115-7ff3-4c81-a7c1-2a1f067b1ece":[1,2,3]}'
>>> orjson.dumps(
        {datetime.datetime(1970, 1, 1, 0, 0, 0): [1, 2, 3]},
        option=orjson.OPT_NON_STR_KEYS | orjson.OPT_NAIVE_UTC,
    )
b'{"1970-01-01T00:00:00+00:00":[1,2,3]}'
这些类型通常按照它们作为值的序列化方式进行序列化,例如,datetime.datetime仍然是RFC 3339字符串,并尊重影响它的选项。例外的是,int序列化不尊重OPT_STRICT_INTEGER。
此选项有创建重复键的风险。这是因为非str对象可能序列化成与现有键相同的str,例如,{"1": true, 1: false}。最后插入到dict中的键将被最后序列化,JSON反序列化器可能假定最后一个键的出现(在上面的例子中,是false)。第一个值将会丢失。
此选项与orjson.OPT_SORT_KEYS兼容。如果使用排序,请注意排序是不稳定的,对于重复键将是不可预测的。
>>> import orjson, datetime
>>> orjson.dumps(
    {"other": 1, datetime.date(1970, 1, 5): 2, datetime.date(1970, 1, 3): 3},
    option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SORT_KEYS
)
b'{"1970-01-03":3,"1970-01-05":2,"other":1}'
这测量了序列化589KiB JSON的过程,其中包括一个包含100个dict的list,每个dict都有365个随机排序的int键,这些键表示纪元时间戳,以及一个str键。对于“str keys”,在序列化之前将键转换为str,并且orjson仍然指定option=orjson.OPT_NON_STR_KEYS(这总是稍微慢一些)。
| 库 | str键(毫秒) | int键(毫秒) | 排序后的int键(毫秒) | 
|---|---|---|---|
| orjson | 1.53 | 2.16 | 4.29 | 
| ujson | 3.07 | 5.65 | |
| rapidjson | 4.29 | ||
| simplejson | 11.24 | 14.50 | 21.86 | 
| json | 7.17 | 8.49 | 
由于ujson崩溃,因此对于排序为空白。由于在转换所有键为str之前尝试排序而引发TypeError,因此json为空白。rapidjson为空白,因为它不支持非str键。可以使用pynonstr脚本重现此问题。
OPT_OMIT_MICROSECONDS
不要序列化datetime.datetime和datetime.time实例上的microsecond字段。
>>> import orjson, datetime
>>> orjson.dumps(
        datetime.datetime(1970, 1, 1, 0, 0, 0, 1),
    )
b'"1970-01-01T00:00:00.000001"'
>>> orjson.dumps(
        datetime.datetime(1970, 1, 1, 0, 0, 0, 1),
        option=orjson.OPT_OMIT_MICROSECONDS,
    )
b'"1970-01-01T00:00:00"'
OPT_PASSTHROUGH_DATACLASS
将dataclasses.dataclass实例传递给default。这允许自定义它们的输出,但速度非常慢。
>>> import orjson, dataclasses
>>>
@dataclasses.dataclass
class User:
    id: str
    name: str
    password: str
def default(obj):
    if isinstance(obj, User):
        return {"id": obj.id, "name": obj.name}
    raise TypeError
>>> orjson.dumps(User("3b1", "asd", "zxc"))
b'{"id":"3b1","name":"asd","password":"zxc"}'
>>> orjson.dumps(User("3b1", "asd", "zxc"), option=orjson.OPT_PASSTHROUGH_DATACLASS)
TypeError: Type is not JSON serializable: User
>>> orjson.dumps(
        User("3b1", "asd", "zxc"),
        option=orjson.OPT_PASSTHROUGH_DATACLASS,
        default=default,
    )
b'{"id":"3b1","name":"asd"}'
OPT_PASSTHROUGH_DATETIME
将datetime.datetime、datetime.date和datetime.time实例传递给default。这允许将日期时间序列化到自定义格式,例如HTTP日期。
>>> import orjson, datetime
>>>
def default(obj):
    if isinstance(obj, datetime.datetime):
        return obj.strftime("%a, %d %b %Y %H:%M:%S GMT")
    raise TypeError
>>> orjson.dumps({"created_at": datetime.datetime(1970, 1, 1)})
b'{"created_at":"1970-01-01T00:00:00"}'
>>> orjson.dumps({"created_at": datetime.datetime(1970, 1, 1)}, option=orjson.OPT_PASSTHROUGH_DATETIME)
TypeError: Type is not JSON serializable: datetime.datetime
>>> orjson.dumps(
        {"created_at": datetime.datetime(1970, 1, 1)},
        option=orjson.OPT_PASSTHROUGH_DATETIME,
        default=default,
    )
b'{"created_at":"Thu, 01 Jan 1970 00:00:00 GMT"}'
如果使用OPT_NON_STR_KEYS,则此选项不会影响字典键中的日期时间。
OPT_PASSTHROUGH_SUBCLASS
将内置类型的子类传递给default。
>>> import orjson
>>>
class Secret(str):
    pass
def default(obj):
    if isinstance(obj, Secret):
        return "******"
    raise TypeError
>>> orjson.dumps(Secret("zxc"))
b'"zxc"'
>>> orjson.dumps(Secret("zxc"), option=orjson.OPT_PASSTHROUGH_SUBCLASS)
TypeError: Type is not JSON serializable: Secret
>>> orjson.dumps(Secret("zxc"), option=orjson.OPT_PASSTHROUGH_SUBCLASS, default=default)
b'"******"'
如果使用OPT_NON_STR_KEYS,则此选项不会影响作为字典键序列化子类。
OPT_SERIALIZE_DATACLASS
这已被弃用,在版本3中没有效果。在版本2中,它用于序列化dataclasses.dataclass实例。更多详情请参阅dataclass。
OPT_SERIALIZE_NUMPY
序列化numpy.ndarray实例。更多详情请参阅numpy。
OPT_SERIALIZE_UUID
这已被弃用,在版本3中没有效果。在版本2中,它用于序列化uuid.UUID实例。更多详情请参阅UUID。
OPT_SORT_KEYS
按排序顺序序列化dict键。默认情况下,序列化顺序未指定。这相当于标准库中的sort_keys=True。
这可以用于确保顺序对于散列或测试是确定性的。它有相当大的性能惩罚,并且通常不推荐使用。
>>> import orjson
>>> orjson.dumps({"b": 1, "c": 2, "a": 3})
b'{"b":1,"c":2,"a":3}'
>>> orjson.dumps({"b": 1, "c": 2, "a": 3}, option=orjson.OPT_SORT_KEYS)
b'{"a":3,"b":1,"c":2}'
这测量了未排序和排序的twitter.json固定文件的序列化。
| 库 | 未排序(毫秒) | 排序(毫秒) | 与orjson相比 | 
|---|---|---|---|
| orjson | 0.32 | 0.54 | 1 | 
| ujson | 1.6 | 2.07 | 3.8 | 
| rapidjson | 1.12 | 1.65 | 3.1 | 
| simplejson | 2.25 | 3.13 | 5.8 | 
| json | 1.78 | 2.32 | 4.3 | 
可以使用pysort脚本重现此基准测试。
排序不是排序/区域设置的感知。
>>> import orjson
>>> orjson.dumps({"a": 1, "ä": 2, "A": 3}, option=orjson.OPT_SORT_KEYS)
b'{"A":3,"a":1,"\xc3\xa4":2}'
这是与标准库、rapidjson、simplejson和ujson相同的排序行为。
dataclass 也可以序列化为映射,但这不会对它们产生影响。
OPT_STRICT_INTEGER
强制整数限制为53位。默认情况下,整数限制为64位,与Python标准库相同。更多信息请参见 int。
OPT_UTC_Z
在 datetime.datetime 实例上序列化UTC时区为 Z 而不是 +00:00。
>>> import orjson, datetime, zoneinfo
>>> orjson.dumps(
        datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=zoneinfo.ZoneInfo("UTC")),
    )
b'"1970-01-01T00:00:00+00:00"'
>>> orjson.dumps(
        datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=zoneinfo.ZoneInfo("UTC")),
        option=orjson.OPT_UTC_Z
    )
b'"1970-01-01T00:00:00Z"'
片段
orjson.Fragment 在文档中包含已序列化的JSON。这是在无需首先通过 loads() 反序列化为Python对象的情况下,从缓存、JSONB字段或单独序列化的对象中包含JSON blob的有效方式。
>>> import orjson
>>> orjson.dumps({"key": "zxc", "data": orjson.Fragment(b'{"a": "b", "c": 1}')})
b'{"key":"zxc","data":{"a": "b", "c": 1}}'
它不会重新格式化:orjson.OPT_INDENT_2 不会影响紧凑的blob,也不会将格式化的JSON blob重写为紧凑格式。
输入必须是 bytes 或 str,并作为位置参数给出。
如果给出的是 str 且输入不是有效的UTF-8,则会引发 orjson.JSONEncodeError。否则,它不会进行验证,并且可以写入无效的JSON。它不会转义字符。实现经过测试,如果给出无效字符串或无效JSON,则不会崩溃。
这与 rapidjson 中的 RawJSON 相似。
反序列化
def loads(__obj: Union[bytes, bytearray, memoryview, str]) -> Any: ...
loads() 将JSON反序列化为Python对象。它反序列化为 dict、list、int、float、str、bool 和 None 对象。
接受 bytes、bytearray、memoryview 和 str 输入。如果输入存在为 memoryview、bytearray 或 bytes 对象,则建议直接传递这些对象而不是创建不必要的 str 对象。即,使用 orjson.loads(b"{}") 而不是 orjson.loads(b"{}".decode("utf-8"))。这具有更低的内存使用率和更低的延迟。
输入必须是有效的UTF-8。
orjson 在整个过程中维护一个映射键的缓存。这通过避免重复字符串来减少了内存使用量。键的长度必须不超过64字节才能被缓存,存储2048个条目。
在调用期间,全局解释器锁(GIL)被持有。
如果给出无效的类型或无效的JSON,则会引发 JSONDecodeError。这包括如果输入包含 NaN、Infinity 或 -Infinity,虽然标准库允许这些,但它们不是有效的JSON。
如果数组或对象的组合递归到1024层深,则会引发 JSONDecodeError。
JSONDecodeError 是 json.JSONDecodeError 和 ValueError 的子类。这是为了与标准库兼容。
类型
数据类
orjson 以原生方式序列化 dataclasses.dataclass 实例。它比其他库快40-50倍,并且避免了与其他库相比序列化 dict 时出现的严重减速。
支持传递所有数据类变体,包括使用 __slots__ 的数据类、冻结数据类、具有可选或默认属性的数据类以及子类。不使用 __slots__ 会有性能优势。
| 库 | dict (ms) | dataclass (ms) | 与orjson相比 | 
|---|---|---|---|
| orjson | 1.40 | 1.60 | 1 | 
| ujson | |||
| rapidjson | 3.64 | 68.48 | 42 | 
| simplejson | 14.21 | 92.18 | 57 | 
| json | 13.28 | 94.90 | 59 | 
这衡量了序列化555KiB的JSON,orjson原生和其他库使用 default 来序列化 dataclasses.asdict() 的输出。这可以使用 pydataclass 脚本来重现。
数据类被序列化为映射,每个属性都会序列化,并且按照类定义上给出的顺序。
>>> import dataclasses, orjson, typing
@dataclasses.dataclass
class Member:
    id: int
    active: bool = dataclasses.field(default=False)
@dataclasses.dataclass
class Object:
    id: int
    name: str
    members: typing.List[Member]
>>> orjson.dumps(Object(1, "a", [Member(1, True), Member(2)]))
b'{"id":1,"name":"a","members":[{"id":1,"active":true},{"id":2,"active":false}]}'
日期时间
orjson 将 datetime.datetime 对象序列化为 RFC 3339 格式,例如,“1970-01-01T00:00:00+00:00”。这是ISO 8601的子集,与标准库中的 isoformat() 兼容。
>>> import orjson, datetime, zoneinfo
>>> orjson.dumps(
    datetime.datetime(2018, 12, 1, 2, 3, 4, 9, tzinfo=zoneinfo.ZoneInfo("Australia/Adelaide"))
)
b'"2018-12-01T02:03:04.000009+10:30"'
>>> orjson.dumps(
    datetime.datetime(2100, 9, 1, 21, 55, 2).replace(tzinfo=zoneinfo.ZoneInfo("UTC"))
)
b'"2100-09-01T21:55:02+00:00"'
>>> orjson.dumps(
    datetime.datetime(2100, 9, 1, 21, 55, 2)
)
b'"2100-09-01T21:55:02"'
datetime.datetime 支持具有 tzinfo 为 None、datetime.timezone.utc、python3.9+ zoneinfo 模块中的时区实例,或来自第三方 pendulum、pytz 或 dateutil/arrow 库的时区实例的时区实例。
使用标准库的 zoneinfo.ZoneInfo 处理时区是最快的。
datetime.time 对象不能有 tzinfo。
>>> import orjson, datetime
>>> orjson.dumps(datetime.time(12, 0, 15, 290))
b'"12:00:15.000290"'
datetime.date 对象将始终序列化。
>>> import orjson, datetime
>>> orjson.dumps(datetime.date(1900, 1, 2))
b'"1900-01-02"'
有关 tzinfo 的错误会导致引发 JSONEncodeError。
要禁用序列化 datetime 对象,请指定选项 orjson.OPT_PASSTHROUGH_DATETIME。
使用“Z”后缀代替“+00:00”来表示UTC(“Zulu”)时间,请使用选项orjson.OPT_UTC_Z。
假设没有时区的日期时间都是UTC,请使用选项orjson.OPT_NAIVE_UTC。
枚举
orjson原生序列化枚举。选项应用于它们的值。
>>> import enum, datetime, orjson
>>>
class DatetimeEnum(enum.Enum):
    EPOCH = datetime.datetime(1970, 1, 1, 0, 0, 0)
>>> orjson.dumps(DatetimeEnum.EPOCH)
b'"1970-01-01T00:00:00"'
>>> orjson.dumps(DatetimeEnum.EPOCH, option=orjson.OPT_NAIVE_UTC)
b'"1970-01-01T00:00:00+00:00"'
不支持类型的成员的枚举可以使用default进行序列化。
>>> import enum, orjson
>>>
class Custom:
    def __init__(self, val):
        self.val = val
def default(obj):
    if isinstance(obj, Custom):
        return obj.val
    raise TypeError
class CustomEnum(enum.Enum):
    ONE = Custom(1)
>>> orjson.dumps(CustomEnum.ONE, default=default)
b'1'
浮点数
orjson在无精度损失和一致舍入的情况下序列化和反序列化双精度浮点数。
orjson.dumps()将不合规JSON的Nan、Infinity和-Infinity序列化为null。
>>> import orjson, ujson, rapidjson, json
>>> orjson.dumps([float("NaN"), float("Infinity"), float("-Infinity")])
b'[null,null,null]'
>>> ujson.dumps([float("NaN"), float("Infinity"), float("-Infinity")])
OverflowError: Invalid Inf value when encoding double
>>> rapidjson.dumps([float("NaN"), float("Infinity"), float("-Infinity")])
'[NaN,Infinity,-Infinity]'
>>> json.dumps([float("NaN"), float("Infinity"), float("-Infinity")])
'[NaN, Infinity, -Infinity]'
整数
orjson默认序列化和反序列化64位整数。支持的范围内是一个有符号64位整数的最小值(-9223372036854775807)到无符号64位整数的最大值(18446744073709551615)。这具有广泛的兼容性,但有些实现只支持53位的整数,例如Web浏览器。对于这些实现,dumps()可以配置为在超过53位范围时引发JSONEncodeError。
>>> import orjson
>>> orjson.dumps(9007199254740992)
b'9007199254740992'
>>> orjson.dumps(9007199254740992, option=orjson.OPT_STRICT_INTEGER)
JSONEncodeError: Integer exceeds 53-bit range
>>> orjson.dumps(-9007199254740992, option=orjson.OPT_STRICT_INTEGER)
JSONEncodeError: Integer exceeds 53-bit range
NumPy
orjson原生序列化numpy.ndarray和单个numpy.float64、numpy.float32、numpy.float16(numpy.half)、numpy.int64、numpy.int32、numpy.int16、numpy.int8、numpy.uint64、numpy.uint32、numpy.uint16、numpy.uint8、numpy.uintp、numpy.intp、numpy.datetime64和numpy.bool实例。
orjson与numpy v1和v2都兼容。
orjson在序列化numpy实例方面比所有比较的库都要快。序列化numpy数据需要指定option=orjson.OPT_SERIALIZE_NUMPY。
>>> import orjson, numpy
>>> orjson.dumps(
        numpy.array([[1, 2, 3], [4, 5, 6]]),
        option=orjson.OPT_SERIALIZE_NUMPY,
)
b'[[1,2,3],[4,5,6]]'
数组必须是一个连续的C数组(C_CONTIGUOUS)和受支持的其中一种数据类型。
注意使用tolist()或orjson.dumps(..., option=orjson.OPT_SERIALIZE_NUMPY)序列化numpy.float32之间的差异:tolist()在序列化之前将转换为double,而orjson的本地路径则不会。这可能导致不同的舍入。
numpy.datetime64实例序列化为RFC 3339字符串,日期时间选项会影响它们。
>>> import orjson, numpy
>>> orjson.dumps(
        numpy.datetime64("2021-01-01T00:00:00.172"),
        option=orjson.OPT_SERIALIZE_NUMPY,
)
b'"2021-01-01T00:00:00.172000"'
>>> orjson.dumps(
        numpy.datetime64("2021-01-01T00:00:00.172"),
        option=(
            orjson.OPT_SERIALIZE_NUMPY |
            orjson.OPT_NAIVE_UTC |
            orjson.OPT_OMIT_MICROSECONDS
        ),
)
b'"2021-01-01T00:00:00+00:00"'
如果数组不是一个连续的C数组,包含不受支持的数据类型,或包含使用不受支持表示的numpy.datetime64(例如,皮秒),orjson将回退到default。在default中,可以指定obj.tolist()。
如果数组不是本地顺序,例如在低端系统上大端值的数组,将引发orjson.JSONEncodeError。
如果数组格式不正确,将引发orjson.JSONEncodeError。
这测量了从具有(50000, 100)维度和numpy.float64值的numpy.ndarray序列化92MiB JSON的过程。
| 库 | 延迟(毫秒) | RSS差(MiB) | 与orjson相比 | 
|---|---|---|---|
| orjson | 194 | 99 | 1.0 | 
| ujson | |||
| rapidjson | 3,048 | 309 | 15.7 | 
| simplejson | 3,023 | 297 | 15.6 | 
| json | 3,133 | 297 | 16.1 | 
这测量了从具有(100000, 100)维度和numpy.int32值的numpy.ndarray序列化100MiB JSON的过程。
| 库 | 延迟(毫秒) | RSS差(MiB) | 与orjson相比 | 
|---|---|---|---|
| orjson | 178 | 115 | 1.0 | 
| ujson | |||
| rapidjson | 1,512 | 551 | 8.5 | 
| simplejson | 1,606 | 504 | 9.0 | 
| json | 1,506 | 503 | 8.4 | 
这测量了从具有(100000, 200)维度和numpy.bool值的numpy.ndarray序列化105MiB JSON的过程。
| 库 | 延迟(毫秒) | RSS差(MiB) | 与orjson相比 | 
|---|---|---|---|
| orjson | 157 | 120 | 1.0 | 
| ujson | |||
| rapidjson | 710 | 327 | 4.5 | 
| simplejson | 931 | 398 | 5.9 | 
| json | 996 | 400 | 6.3 | 
在这些基准测试中,orjson原生序列化,ujson为空,因为它不支持默认参数,其他库通过default序列化ndarray.tolist()。RSS列测量序列化期间的峰值内存使用。这可以使用pynumpy脚本重现。
orjson没有安装或编译对numpy的依赖。实现是独立的,使用PyArrayInterface读取numpy.ndarray。
字符串
orjson对UTF-8的符合性很严格。这比标准库的json模块更严格,它将序列化和反序列化无效UTF-8的UTF-16代理,例如"\ud800"。
如果orjson.dumps()接收到不包含有效UTF-8的str,将引发orjson.JSONEncodeError。如果loads()接收到无效UTF-8,将引发orjson.JSONDecodeError。
orjson和rapidjson是唯一在坏输入上一致引发错误的比较JSON库。
>>> import orjson, ujson, rapidjson, json
>>> orjson.dumps('\ud800')
JSONEncodeError: str is not valid UTF-8: surrogates not allowed
>>> ujson.dumps('\ud800')
UnicodeEncodeError: 'utf-8' codec ...
>>> rapidjson.dumps('\ud800')
UnicodeEncodeError: 'utf-8' codec ...
>>> json.dumps('\ud800')
'"\\ud800"'
>>> orjson.loads('"\\ud800"')
JSONDecodeError: unexpected end of hex escape at line 1 column 8: line 1 column 1 (char 0)
>>> ujson.loads('"\\ud800"')
''
>>> rapidjson.loads('"\\ud800"')
ValueError: Parse error at offset 1: The surrogate pair in string is invalid.
>>> json.loads('"\\ud800"')
'\ud800'
为了尽可能正确地反序列化无效输入,首先使用errors参数的replace或lossy选项对bytes进行解码。
>>> import orjson
>>> orjson.loads(b'"\xed\xa0\x80"')
JSONDecodeError: str is not valid UTF-8: surrogates not allowed
>>> orjson.loads(b'"\xed\xa0\x80"'.decode("utf-8", "replace"))
'���'
UUID
orjson将uuid.UUID实例序列化为RFC 4122格式,例如,“f81d4fae-7dec-11d0-a765-00a0c91e6bf6”。
>>> import orjson, uuid
>>> orjson.dumps(uuid.UUID('f81d4fae-7dec-11d0-a765-00a0c91e6bf6'))
b'"f81d4fae-7dec-11d0-a765-00a0c91e6bf6"'
>>> orjson.dumps(uuid.uuid5(uuid.NAMESPACE_DNS, "python.org"))
b'"886313e1-3b8a-5372-9b90-0c9aee199e5d"'
测试
该库具有全面的测试。它对JSONTestSuite和nativejson-benchmark仓库中的固定值进行了测试。它被测试为不会因Big List of Naughty Strings而崩溃。它被测试为不会泄漏内存。它被测试为不会因无效的UTF-8而崩溃或不接受。它还有集成测试,用于在Web服务器(使用多进程/分叉工作进程的gunicorn)和多线程时使用库。它还使用了ultrajson库的一些测试。
orjson是所比较库中最正确的。此图显示了每个库如何处理来自JSONTestSuite和nativejson-benchmark测试的342个JSON固定值。
| 库 | 不拒绝无效的JSON文档 | 不反序列化有效的JSON文档 | 
|---|---|---|
| orjson | 0 | 0 | 
| ujson | 31 | 0 | 
| rapidjson | 6 | 0 | 
| simplejson | 10 | 0 | 
| json | 17 | 0 | 
这表明所有库都能反序列化有效的JSON,但只有orjson正确地拒绝了给定的无效JSON固定值。错误大部分是由于接受无效的字符串和数字。
可以使用pycorrectness脚本来重现上面的图。
性能
orjson的序列化和反序列化性能优于ultrajson、rapidjson、simplejson和json。基准测试是在真实数据的固定值上进行的
- 
twitter.json,631.5KiB,Twitter上搜索“一”的结果,包含CJK字符串、字符串字典和字典数组,缩进。 
- 
github.json,55.8KiB,GitHub活动源,包含字符串字典和字典数组,未缩进。 
- 
citm_catalog.json,1.7MiB,音乐会数据,包含嵌套的字符串字典和整数数组,缩进。 
- 
canada.json,2.2MiB,加拿大边界的GeoJSON格式坐标,包含浮点数和数组,缩进。 
延迟
twitter.json序列化
| 库 | 中值延迟(毫秒) | 每秒操作数 | 相对(延迟) | 
|---|---|---|---|
| orjson | 0.1 | 8377 | 1 | 
| ujson | 0.9 | 1088 | 7.3 | 
| rapidjson | 0.8 | 1228 | 6.8 | 
| simplejson | 1.9 | 531 | 15.6 | 
| json | 1.4 | 744 | 11.3 | 
twitter.json反序列化
| 库 | 中值延迟(毫秒) | 每秒操作数 | 相对(延迟) | 
|---|---|---|---|
| orjson | 0.6 | 1811 | 1 | 
| ujson | 1.2 | 814 | 2.1 | 
| rapidjson | 2.1 | 476 | 3.8 | 
| simplejson | 1.6 | 626 | 3 | 
| json | 1.8 | 557 | 3.3 | 
github.json序列化
| 库 | 中值延迟(毫秒) | 每秒操作数 | 相对(延迟) | 
|---|---|---|---|
| orjson | 0.01 | 104424 | 1 | 
| ujson | 0.09 | 10594 | 9.8 | 
| rapidjson | 0.07 | 13667 | 7.6 | 
| simplejson | 0.2 | 5051 | 20.6 | 
| json | 0.14 | 7133 | 14.6 | 
github.json反序列化
| 库 | 中值延迟(毫秒) | 每秒操作数 | 相对(延迟) | 
|---|---|---|---|
| orjson | 0.05 | 20069 | 1 | 
| ujson | 0.11 | 8913 | 2.3 | 
| rapidjson | 0.13 | 8077 | 2.6 | 
| simplejson | 0.11 | 9342 | 2.1 | 
| json | 0.11 | 9291 | 2.2 | 
citm_catalog.json序列化
| 库 | 中值延迟(毫秒) | 每秒操作数 | 相对(延迟) | 
|---|---|---|---|
| orjson | 0.3 | 3757 | 1 | 
| ujson | 1.7 | 598 | 6.3 | 
| rapidjson | 1.3 | 768 | 4.9 | 
| simplejson | 8.3 | 120 | 31.1 | 
| json | 3 | 331 | 11.3 | 
citm_catalog.json反序列化
| 库 | 中值延迟(毫秒) | 每秒操作数 | 相对(延迟) | 
|---|---|---|---|
| orjson | 1.4 | 730 | 1 | 
| ujson | 2.6 | 384 | 1.9 | 
| rapidjson | 4 | 246 | 3 | 
| simplejson | 3.7 | 271 | 2.7 | 
| json | 3.7 | 267 | 2.7 | 
canada.json序列化
| 库 | 中值延迟(毫秒) | 每秒操作数 | 相对(延迟) | 
|---|---|---|---|
| orjson | 2.4 | 410 | 1 | 
| ujson | 9.6 | 104 | 3.9 | 
| rapidjson | 28.7 | 34 | 11.8 | 
| simplejson | 49.3 | 20 | 20.3 | 
| json | 30.6 | 32 | 12.6 | 
canada.json反序列化
| 库 | 中值延迟(毫秒) | 每秒操作数 | 相对(延迟) | 
|---|---|---|---|
| orjson | 3 | 336 | 1 | 
| ujson | 7.1 | 141 | 2.4 | 
| rapidjson | 20.1 | 49 | 6.7 | 
| simplejson | 16.8 | 59 | 5.6 | 
| json | 18.2 | 55 | 6.1 | 
内存
由于解析时使用持久缓冲区,orjson 3.7.0的基线内存使用量高于其他库。反序列化时的增量内存使用量与标准库和其他第三方库相似。
第一列测量在导入库并读取固定值后的RSS,第二列测量在固定值上反复调用loads()后的RSS增加。
twitter.json
| 库 | 导入,read() RSS(MiB) | loads() RSS增加(MiB) | 
|---|---|---|
| orjson | 15.7 | 3.4 | 
| ujson | 16.4 | 3.4 | 
| rapidjson | 16.6 | 4.4 | 
| simplejson | 14.5 | 1.8 | 
| json | 13.9 | 1.8 | 
github.json
| 库 | 导入,read() RSS(MiB) | loads() RSS增加(MiB) | 
|---|---|---|
| orjson | 15.2 | 0.4 | 
| ujson | 15.4 | 0.4 | 
| rapidjson | 15.7 | 0.5 | 
| simplejson | 13.7 | 0.2 | 
| json | 13.3 | 0.1 | 
citm_catalog.json
| 库 | 导入,read() RSS(MiB) | loads() RSS增加(MiB) | 
|---|---|---|
| orjson | 16.8 | 10.1 | 
| ujson | 17.3 | 10.2 | 
| rapidjson | 17.6 | 28.7 | 
| simplejson | 15.8 | 30.1 | 
| json | 14.8 | 20.5 | 
canada.json
| 库 | 导入,read() RSS(MiB) | loads() RSS增加(MiB) | 
|---|---|---|
| orjson | 17.2 | 22.1 | 
| ujson | 17.4 | 18.3 | 
| rapidjson | 18 | 23.5 | 
| simplejson | 15.7 | 21.4 | 
| json | 15.4 | 20.4 | 
重现
上述测量是在Linux(amd64)上的Python 3.11.9和orjson 3.10.6、ujson 5.10.0、python-rapidson 1.18和simplejson 3.19.2上进行的。
可以使用pybench和graph脚本来重现延迟结果。可以使用pymem脚本来重现内存结果。
问题
为什么我无法从PyPI安装它?
可能需要将pip升级到20.3或更高版本,以支持最新的manylinux_x_y或universal2 wheel格式。
“Cargo,Rust包管理器,未安装或不在PATH中。”
当PyPI上没有针对您的平台的二进制轮子(如manylinux)时,会出现这种情况。您可以通过rustup或包管理器安装Rust,然后它会进行编译。
它能否反序列化为dataclasses、UUIDs、十进制数等,或者支持object_hook吗?
不,这需要一个指定预期类型和处理错误等的模式。这可以通过比这更高一级的数据验证库来解决。
它能否序列化为str?
不,序列化的blob应该使用bytes类型。
打包
要打包或json,至少需要Rust 1.72和maturin构建工具。推荐的构建命令是
maturin build --release --strip
它还受益于有一个C构建环境来编译更快的反序列化后端。请参阅该项目使用clang和LTO的manylinux_2_28构建示例。
项目自己的CI测试针对nightly-2024-08-05和稳定版1.72。明智的做法是将nightly版本锁定,因为该渠道可能会引入破坏性更改。
orjson在Linux上针对amd64、aarch64、arm7、ppc64le和s390x进行了测试。在macOS上,它针对aarch64或amd64进行了测试,并根据版本进行交叉编译。对于Windows,它针对amd64和i686进行了测试。
除了libc之外,没有其他运行时依赖项。
PyPI上的源分布包含所有依赖项的源代码,并且可以在没有网络访问的情况下构建。可以从https://files.pythonhosted.org/packages/source/o/orjson/orjson-${version}.tar.gz下载文件。
orjson的测试包含在PyPI上的源分布中。运行测试的要求在test/requirements.txt中指定。测试应在构建过程中运行。可以使用pytest -q test运行。
许可证
orjson由ijl编写,邮箱:ijl@mailbox.org,版权所有 2018 - 2024,您可以选择Apache 2许可证或MIT许可证。
项目详情
下载文件
下载适用于您平台的项目文件。如果您不确定该选择哪一个,请了解有关安装包的更多信息。
源分布
构建分布
orjson-3.10.7.tar.gz 的哈希值
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3 | |
| MD5 | 15887b76f1f4c03c3fb00a56c404af19 | |
| BLAKE2b-256 | 9e03821c8197d0515e46ea19439f5c5d5fd9a9889f76800613cfac947b5d7845 | 
哈希值 for orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad | |
| MD5 | 853d0938a83c7fe101b5e92bbd800bec | |
| BLAKE2b-256 | e21c3ef8d83d7c6a619ad3d69a4d5318591b4ce5862e6eda7c26bbe8208652ca | 
哈希值 for orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c | |
| MD5 | 70a5b6ee4faca8b6e0a0725e40b0146a | |
| BLAKE2b-256 | 0465f2a03fd1d4f0308f01d372e004c049f7eb9bc5676763a15f20f383fa9c01 | 
哈希值 for orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe | |
| MD5 | 8b6579a8e513af557efdd135418b68c2 | |
| BLAKE2b-256 | 737f8d6ccd64a6f8bdbfe6c9be7c58aeb8094aa52a01fbbb2cda42ff7e312bd7 | 
哈希值 for orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149 | |
| MD5 | 4ace9730c8c14691086b247027b4b7ce | |
| BLAKE2b-256 | 1505121af8a87513c56745d01ad7cf215c30d08356da9ad882ebe2ba890824cd | 
哈希值 for orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b | |
| MD5 | 850bf1cd2a36d77e3400348c7c57c7c4 | |
| BLAKE2b-256 | 021ad11805670c29d3a1b29fc4bd048dc90b094784779690592efe8c9f71249a | 
哈希值 for orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5 | |
| MD5 | b70f8806719b27256bfe5556c9e9d085 | |
| BLAKE2b-256 | 177e254189d9b6df89660f65aec878d5eeaa5b1ae371bd2c458f85940445d36f | 
哈希值 for orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09 | |
| MD5 | 2228ae083124649c499da37d2e892dd8 | |
| BLAKE2b-256 | a06b34e6904ac99df811a06e42d8461d47b6e0c9b86e2fe7ee84934df6e35f0d | 
哈希值 for orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864 | |
| MD5 | e39554017342f730212592eeeb882950 | |
| BLAKE2b-256 | b100414f8d4bc5ec3447e27b5c26b4e996e4ef08594d599e79b3648f64da060c | 
哈希值 用于 orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313 | |
| MD5 | c47e91f03ce33ecbada084730bc7ef90 | |
| BLAKE2b-256 | 30befd646fb1a461de4958a6eacf4ecf064b8d5479c023e0e71cc89b28fa91ac | 
哈希值 用于 orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93 | |
| MD5 | 300f4dc66905edeba82f17f7a3b8494e | |
| BLAKE2b-256 | c527e40bc7d79c4afb7e9264f22320c285d06d2c9574c9c682ba0f1be3012833 | 
哈希值 用于 orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3 | |
| MD5 | 2d89778e3c82dcad0473a6d0cd98f34c | |
| BLAKE2b-256 | 6084e495edb919ef0c98d054a9b6d05f2700fdeba3886edd58f1c4dfb25d514a | 
哈希值 用于 orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f | |
| MD5 | 134bf2d8078d89763b4131426a7d24d6 | |
| BLAKE2b-256 | 147cb4ecc2069210489696a36e42862ccccef7e49e1454a3422030ef52881b01 | 
哈希值 用于 orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0 | |
| MD5 | ac2d2ce1a7cfa88ccca17bb4ef3d4475 | |
| BLAKE2b-256 | 53b910abe9089bdb08cd4218cc45eb7abfd787c82cf301cecbfe7f141542d7f4 | 
哈希值 用于 orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6 | |
| MD5 | 7755171561323635fdd680b72a268ced | |
| BLAKE2b-256 | bbab1185e472f15c00d37d09c395e478803ed0eae7a3a3d055a5f3885e1ea136 | 
哈希值 用于 orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6 | |
| MD5 | 960590238707ee008a6d43350f834254 | |
| BLAKE2b-256 | d3cb55205f3f1ee6ba80c0a9a18ca07423003ca8de99192b18be30f1f31b4cdd | 
哈希值 用于 orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e | |
| MD5 | 5f8befd6891251b20bf5881fad9bb1d6 | |
| BLAKE2b-256 | 92ee702d5e8ccd42dc2b9d1043f22daa1ba75165616aa021dc19fb0c5a726ce8 | 
哈希值 用于 orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a | |
| MD5 | af0b570fe5b85f6f90b3cc883f391baf | |
| BLAKE2b-256 | 669fe6a11b5d1ad11e9dc869d938707ef93ff5ed20b53d6cda8b5e2ac532a9d2 | 
哈希值 用于 orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0 | |
| MD5 | c35571dc56025d2bef27fdda124cab40 | |
| BLAKE2b-256 | 9db6ed61e87f327a4cbb2075ed0716e32ba68cb029aa654a68c3eb27803050d8 | 
哈希值 用于 orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09 | |
| MD5 | 4f158b1a876d5775ae2e03923f7fb3be | |
| BLAKE2b-256 | b972d90bd11e83a0e9623b3803b079478a93de8ec4316c98fa66110d594de5fa | 
哈希值 用于 orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2 | |
| MD5 | a069436255f0a118c72521779a21c894 | |
| BLAKE2b-256 | 89c9dd286c97c2f478d43839bd859ca4d9820e2177d4e07a64c516dc3e018062 | 
哈希值 用于 orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84 | |
| MD5 | da6fbd2e92bfb98501a47fe2680d0dd0 | |
| BLAKE2b-256 | a6d8eee30caba21a8d6a9df06d2519bb0ecd0adbcd57f2e79d360de5570031cf | 
哈希值 用于 orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250 | |
| MD5 | 41de8e95b3e1c8c04e323585cc5d0c2e | |
| BLAKE2b-256 | 820a1f09c12d15b1e83156b7f3f621561d38650fe5b8f39f38f04a64de1a87fc | 
哈希值 用于 orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91 | |
| MD5 | 457e4dab60dbe286146242c7cd0faf40 | |
| BLAKE2b-256 | b6bcfbd345d771a73cacc5b0e774d034cd081590b336754c511f4ead9fdc4cf1 | 
哈希值 用于 orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9 | |
| MD5 | dae12750f1aaaa7d39134aa3fd1c719c | |
| BLAKE2b-256 | 7f7eef8522dbba112af6cc52227dcc746dd3447c7d53ea8cea35740239b547ee | 
哈希值 用于 orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c | |
| MD5 | 536e60d7c22ac86c351f0b05ab7b8be5 | |
| BLAKE2b-256 | 04dad03d72b54bdd60d05de372114abfbd9f05050946895140c6ff5f27ab8f49 | 
哈希值 用于 orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7 | |
| MD5 | f50628a0e0453d464328877b10ab0a29 | |
| BLAKE2b-256 | dd471ddff6e23fe5f4aeaaed996a3cde422b3eaac4558c03751723e106184c68 | 
哈希值 用于 orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac | |
| MD5 | a6f25d06469acccd3ae132e5fb552d33 | |
| BLAKE2b-256 | fe0eefbd0a2d25f8e82b230eb20b6b8424be6dd95b6811b669be9af16234b6db | 
哈希值 用于 orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12 | |
| MD5 | 73c1907bc4824c22e52225ef30e7c8c3 | |
| BLAKE2b-256 | 491260931cf808b9334f26210ab496442f4a7a3d66e29d1cf12e0a01857e756f | 
哈希值 用于 orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5 | |
| MD5 | 46f075ea83645b7ec01cc4d7c88962cb | |
| BLAKE2b-256 | d7152c1ca80d4e37780514cc369004fce77e2748b54857b62eb217e9a243a669 | 
哈希值 用于 orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd | |
| MD5 | b2947e0f2e9510024df54522b25e5cf3 | |
| BLAKE2b-256 | c1c65d5c556720f8a31c5618db7326f6de6c07ddfea72497c1baa69fca24e1ad | 
哈希值 用于 orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff | |
| MD5 | b2f514da1e166c0ebe31dbab5475098b | |
| BLAKE2b-256 | 6cc197b5bb1869572483b0e060264180fe5417a836ed46c09166f0dc6bb1d42d | 
哈希值 用于 orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f | |
| MD5 | c5a51dd2a87c605682f6f0ae89006344 | |
| BLAKE2b-256 | 0402bcb6ee82ecb5bc8f7487bce2204db9e9d8818f5fe7a3cad1625254f8d3a7 | 
哈希值 用于 orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9 | |
| MD5 | 7fb4b085ad57ddae29a3c24071369987 | |
| BLAKE2b-256 | ba5b89f2d5cda6c7bcad2067a87407aa492392942118969d548bc77ab4e9c818 | 
哈希值 用于 orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412 | |
| MD5 | ca943a19c838b30bd846bc724be9f6e4 | |
| BLAKE2b-256 | a34aa041b6c95f623c28ccab87ce0720ac60cd0734f357774fd7212ff1fd9077 | 
哈希值 用于 orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960 | |
| MD5 | 1333e3e15a78e1ba1ce38617690ac22f | |
| BLAKE2b-256 | b8e5f3cb8f766e7f5e5197e884d63fba320aa4f32a04a21b68864c71997cb17e | 
哈希值 用于 orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20 | |
| MD5 | 1919f7b33f3d1ae7c41838b6fc26cdb0 | |
| BLAKE2b-256 | 088c23813894241f920e37ae363aa59a6a0fdb06e90afd60ad89e5a424113d1c | 
哈希值 用于 orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866 | |
| MD5 | 12c1cf6528719fe8a4f3ab026411a1b8 | |
| BLAKE2b-256 | 064790ff5f8522d371b8ec117791db13a14880647cad22a6d3c4369026ec0f48 | 
哈希值 用于 orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354 | |
| MD5 | da6aa2d7f37ca13109111afb965d5d4e | |
| BLAKE2b-256 | cbddf5b385ab593974efd082986f8c6f4f6d07715f7321d908ca16bc4ecd70cd | 
哈希值 用于 orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98 | |
| MD5 | 46d011f6b773509d1b204e072a0bd355 | |
| BLAKE2b-256 | 2513a66f4873ed57832aab57dd8b49c91c4c22b35fb1fa0d1dce3bf8928f2fe0 | 
哈希值 用于 orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0 | |
| MD5 | 897e5bfdbef3cc5d92e7b87bc3bb1aa2 | |
| BLAKE2b-256 | 571c6d195253a25fdc9770056e3fed96d2e1105b2108c2e7f05bb2178f2e89cb | 
哈希值 用于 orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23 | |
| MD5 | 92f003b9d710a5b605952ae297e327ae | |
| BLAKE2b-256 | 8487272c9abc2c45f535f5b7d05219d94e3962a8cb2866a72a4778289358a873 | 
哈希值 用于 orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225 | |
| MD5 | fa638ae27389252913053cb266d7e9e6 | |
| BLAKE2b-256 | fe6635857fdb7883d6f51c5d212693c51ad72f8b25b73fc043f424760b735ec6 | 
哈希值 用于 orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1 | |
| MD5 | 83eb8d43b2f753a5ecfee952907f8c24 | |
| BLAKE2b-256 | e022218233b8038a83ca8df0c6e7e28270ad5a2cd02a2e2ada0a30f33d018601 | 
哈希值 用于 orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469 | |
| MD5 | 58b6a1bdaa0a0c0ac65f6e7f0157a4eb | |
| BLAKE2b-256 | 6e54cf4838db05cc5c3e2ccd8b85e80239789457fc8a20071910e8f97cd7fa44 |