orjson 是一個快速、正確的 Python JSON 函式庫。它被評為最快的 JSON Python 庫,並且比標準 json 庫或其他第三方庫更正確。它本機序列化資料類別、日期時間、numpy 和 UUID 實例。
orjson.dumps() 的速度大約是json
的 10 倍,序列化常見類型和子類型,有一個default
參數供呼叫者指定如何序列化任意類型,並且有許多控制輸出的標誌。
orjson.loads() 的速度大約是json
的 2 倍,並且嚴格符合 UTF-8 和 RFC 8259(「JavaScript 物件表示法 (JSON) 資料交換格式」)。
該庫不提供檔案、行分隔 JSON 檔案等的讀取和寫入功能。
orjson 支援 CPython 3.8、3.9、3.10、3.11、3.12、3.13 和 3.14。
它分發適用於 Linux 的 amd64/x86_64、i686/x86、aarch64/armv8、arm7、POWER/ppc64le 和 s390x 輪子、適用於 macOS 的 amd64 和 aarch64 輪子以及適用於 Windows 的 68648 和 i6
orjson 不支援也不會支援 PyPy、Android/iOS 的嵌入式 Python 建置或 PEP 554 子解釋器。
版本遵循語義版本控制,並且在沒有選擇加入標誌的情況下序列化新物件類型被視為重大變更。
orjson 已獲得 Apache 2.0 和 MIT 許可證的許可。儲存庫和問題追蹤器是 github.com/ijl/orjson,補丁可以在那裡提交。儲存庫中有一個可用的變更日誌。
若要從 PyPI 安裝 Wheel,請安裝orjson
套件。
以requirements.in
或requirements.txt
格式指定:
orjson >= 3.10,<4
在pyproject.toml
格式中,指定:
orjson = " ^3.10 "
要製作輪子,請參閱包裝。
這是指定選項的序列化和反序列化的範例:
> >> 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 ]]}
dict
str
int
比list
2 序列化更多類型。這更快並且更類似於標準庫。可以使用orjson.OPT_PASSTHROUGH_SUBCLASS
來停用它。 dataclasses.dataclass
實例現在預設序列化,並且無法在default
函數中自訂,除非指定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
替換,且不支援其他層級的縮排。
ensure_ascii
目前可能不相關,且 UTF-8 字元無法轉義為 ASCII。
def dumps (
__obj : Any ,
default : Optional [ Callable [[ Any ], Any ]] = ...,
option : Optional [ int ] = ...,
) -> bytes : ...
dumps()
將 Python 物件序列化為 JSON。
它本numpy.ndarray
序列化str
、 dict
、 list
、 tuple
、 int
、 float
、 bool
、 None
、 dataclasses.dataclass
、 typing.TypedDict
、 datetime.datetime
、 datetime.date
、 datetime.time
、 uuid.UUID
、 orjson.Fragment
. orjson.Fragment
它default
支援任意類型。它序列化str
、 int
、 dict
、 list
、 dataclasses.dataclass
和enum.Enum
的子類別。它不會序列化tuple
的子類,以避免將namedtuple
物件序列化為陣列。若要避免序列化子類,請指定選項orjson.OPT_PASSTHROUGH_SUBCLASS
。
輸出是包含 UTF-8 的bytes
物件。
全域解釋器鎖定 (GIL) 在呼叫期間保持不變。
它會在不受支援的類型上引發JSONEncodeError
。此異常訊息描述了無效對象,並帶有錯誤訊息Type is not JSON serializable: ...
。若要解決此問題,請指定預設值。
它會在包含無效 UTF-8 的str
上引發JSONEncodeError
。
預設情況下,如果整數超過 64 位,或使用OPT_STRICT_INTEGER
超過 53 位,則會引發JSONEncodeError
。
如果dict
具有str
以外類型的鍵,則會引發JSONEncodeError
,除非指定了OPT_NON_STR_KEYS
。
如果default
的輸出遞歸到default
處理深度超過 254 層,則會引發JSONEncodeError
。
它會引發循環引用上的JSONEncodeError
。
如果不支援日期時間物件上的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
> >>
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}'
若要修改資料的序列化方式,請指定option
。每個option
都是orjson
中的整數常數。若要指定多個選項,請將它們屏蔽在一起,例如option=orjson.OPT_STRICT_INTEGER | orjson.OPT_NAIVE_UTC
。
將n
附加到輸出。這是dumps(...) + "n"
模式的便利與最佳化。 bytes
物件是不可變的,此模式複製原始內容。
> >> import orjson
> >> orjson . dumps ([])
b"[]"
> >> orjson . dumps ([], option = orjson . OPT_APPEND_NEWLINE )
b"[] n "
漂亮的列印輸出,縮排兩個空格。這相當於標準函式庫中的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):
圖書館 | 緊湊(毫秒) | 漂亮(女士) | 與 orjson |
---|---|---|---|
或json | 0.01 | 0.02 | 1 |
json | 0.13 | 0.54 | 34 |
這測量序列化 citm_catalog.json 固定裝置,由於嵌套和換行的數量,更糟糕的情況是緊湊(489KiB)或漂亮(1.1MiB):
圖書館 | 緊湊(毫秒) | 漂亮(女士) | 與 orjson |
---|---|---|---|
或json | 0.25 | 0.45 | 1 |
json | 3.01 | 24.42 | 54.4 |
這可以使用pyindent
腳本來重現。
將沒有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"'
序列化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
鍵比其他函式庫更快。對於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
鍵,每個鍵的值都是一個整數。在「strkeys」中,鍵在序列化之前被轉換為str
,而orjson仍然指定option=orjson.OPT_NON_STR_KEYS
(這總是有點慢)。
圖書館 | str 鍵(毫秒) | 整數鍵(毫秒) | int 鍵已排序(毫秒) |
---|---|---|---|
或json | 0.5 | 0.93 | 2.08 |
json | 2.72 | 3.59 |
json 為空,因為在將所有鍵轉換為str
之前嘗試排序時會引發TypeError
。這可以使用pynonstr
腳本重現。
不要序列化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"'
將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"}'
將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,這不會影響dict
鍵中的日期時間。
將內建類型的子類別傳遞給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,這不會影響將子類別序列化為dict
鍵。
這已dataclasses.dataclass
棄用,並且在版本 3 中無效。有關更多信息,請參閱數據類。
序列化numpy.ndarray
實例。有關更多信息,請參閱 numpy.
這已被棄用,並且在版本 3 中uuid.UUID
。有關更多信息,請參閱 UUID。
依排序順序序列化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 |
---|---|---|---|
或json | 0.11 | 0.3 | 1 |
json | 1.36 | 1.93 | 6.4 |
可以使用pysort
腳本重現基準測試。
排序不支援排序規則/區域設定:
> >> import orjson
> >> orjson . dumps ({ "a" : 1 , "ä" : 2 , "A" : 3 }, option = orjson . OPT_SORT_KEYS )
b'{"A":3,"a":1," xc3 xa4 ":2}'
這與標準庫的排序行為相同。
dataclass
也序列化為映射,但這對它們沒有影響。
對整數強制 53 位元限制。否則限制為 64 位,與 Python 標準函式庫相同。有關更多信息,請參閱 int.
將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。這是一種包含來自快取、JSONB 欄位或單獨序列化物件的 JSON blob 的有效方法,無需先透過loads()
反序列化為 Python 物件。
> >> 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,則不會崩潰。
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
的實例。與序列化dict
相比,它序列化實例的速度是其他庫的 40-50 倍,並且避免了其他庫中出現的嚴重減速。
支援傳遞資料類別的所有變體,包括使用__slots__
資料類別、凍結資料類別、具有可選或預設屬性的資料類別以及子類別。不使用__slots__
會帶來效能優勢。
圖書館 | 聽寫(毫秒) | 數據類(毫秒) | 與 orjson |
---|---|---|---|
或json | 0.43 | 0.95 | 1 |
json | 5.81 | 38.32 | 40 |
這測量了序列化 555KiB 的 JSON、或本機 json 以及其他函式庫,使用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.