orjson은 빠르고 정확한 Python용 JSON 라이브러리입니다. JSON에 대한 가장 빠른 Python 라이브러리로 벤치마킹되었으며 표준 json 라이브러리 또는 기타 타사 라이브러리보다 더 정확합니다. 기본적으로 데이터 클래스, 날짜/시간, numpy 및 UUID 인스턴스를 직렬화합니다.
orjson.dumps()는 json
보다 10배 빠르고, 일반적인 유형과 하위 유형을 직렬화하고, 호출자가 임의 유형을 직렬화하는 방법을 지정하는 default
매개변수를 가지며, 출력을 제어하는 여러 플래그를 갖습니다.
orjson.loads()는 json
보다 2배 빠르며 UTF-8 및 RFC 8259("JSON(JavaScript Object Notation) 데이터 교환 형식")을 엄격하게 준수합니다.
파일, 줄로 구분된 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용 amd64 및 i686/x86 휠을 배포합니다.
orjson은 PyPy, Android/iOS용 내장 Python 빌드 또는 PEP 554 하위 해석기를 지원하지 않으며 앞으로도 지원하지 않습니다.
릴리스는 의미 체계 버전 관리를 따르며 옵트인 플래그 없이 새 객체 유형을 직렬화하는 것은 주요 변경으로 간주됩니다.
orjson은 Apache 2.0 및 MIT 라이선스에 따라 라이선스가 부여됩니다. 저장소 및 문제 추적기는 github.com/ijl/orjson이며 패치는 해당 위치에 제출될 수 있습니다. 저장소에 CHANGELOG가 있습니다.
PyPI에서 휠을 설치하려면 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 ]]}
orjson 버전 3은 버전 2보다 더 많은 유형을 직렬화합니다. 이제 str
, int
, dict
및 list
의 하위 클래스가 직렬화됩니다. 이는 표준 라이브러리와 더 빠르고 유사합니다. orjson.OPT_PASSTHROUGH_SUBCLASS
로 비활성화할 수 있습니다. dataclasses.dataclass
인스턴스는 이제 기본적으로 직렬화되며 option=orjson.OPT_PASSTHROUGH_DATACLASS
지정되지 않으면 default
함수에서 사용자 정의할 수 없습니다. 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으로 직렬화합니다.
기본적으로 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
의 하위 클래스를 직렬화합니다. namedtuple
객체를 배열로 직렬화하는 것을 피하기 위해 tuple
의 하위 클래스를 직렬화하지 않습니다. 하위 클래스 직렬화를 방지하려면 orjson.OPT_PASSTHROUGH_SUBCLASS
옵션을 지정하세요.
출력은 UTF-8을 포함하는 bytes
열 객체입니다.
전역 인터프리터 잠금(GIL)은 호출 기간 동안 유지됩니다.
지원되지 않는 유형에 대해 JSONEncodeError
발생합니다. 이 예외 메시지는 Type is not JSON serializable: ...
오류 메시지와 함께 잘못된 개체를 설명합니다. 이 문제를 해결하려면 기본값을 지정하세요.
잘못된 UTF-8이 포함된 str
에서 JSONEncodeError
발생합니다.
기본적으로 64비트를 초과하거나 OPT_STRICT_INTEGER
사용하면 53비트를 초과하는 정수에 대해 JSONEncodeError
발생합니다.
OPT_NON_STR_KEYS
가 지정되지 않는 한 dict
str
이외의 유형의 키가 있으면 JSONEncodeError
발생합니다.
default
출력이 default
으로 254개 이상의 레벨을 처리하도록 반복되면 JSONEncodeError
발생합니다.
순환 참조에서 JSONEncodeError
발생합니다.
datetime 객체의 tzinfo
지원되지 않으면 JSONEncodeError
발생합니다.
JSONEncodeError
는 TypeError
의 하위 클래스입니다. 이는 표준 라이브러리와의 호환성을 위한 것입니다.
default
으로 예외로 인해 실패가 발생한 경우 JSONEncodeError
원래 예외를 __cause__
로 연결합니다.
서브클래스 또는 임의 유형을 직렬화하려면 지원되는 유형을 반환하는 콜러블로 default
지정하십시오. default
함수, 람다 또는 호출 가능한 클래스 인스턴스일 수 있습니다. 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은 Pretty Printing에서 가장 빠른 비교 라이브러리이며 표준 라이브러리보다 Pretty Print 속도 저하가 훨씬 적습니다. 이 옵션은 다른 모든 옵션과 호환됩니다.
> >> 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) | 꽤 (밀리초) | 대 orjson |
---|---|---|---|
orjson | 0.01 | 0.02 | 1 |
JSON | 0.13 | 0.54 | 34 |
이는 citm_catalog.json 고정 장치의 직렬화를 측정합니다. 중첩 및 줄바꿈의 양으로 인해 최악의 경우에 해당하는 소형(489KiB) 또는 예쁜(1.1MiB)으로 표시됩니다.
도서관 | 컴팩트(ms) | 꽤 (밀리초) | 대 orjson |
---|---|---|---|
orjson | 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}'
이는 100개의 dict
list
으로 구성된 589KiB의 JSON 직렬화를 측정합니다. 각 dict
에는 에포크 타임스탬프를 나타내는 365개의 무작위로 정렬된 int
키와 하나의 str
키가 있고 각 키의 값은 단일 정수입니다. "str 키"에서 키는 직렬화 전에 str
로 변환되었으며 orjson은 여전히 option=orjson.OPT_NON_STR_KEYS
(항상 다소 느림)를 지정합니다.
도서관 | str 키(ms) | 정수 키(ms) | int 키 정렬(ms) |
---|---|---|---|
orjson | 0.5 | 0.93 | 2.08 |
JSON | 2.72 | 3.59 |
모든 키를 str
로 변환하기 전에 정렬을 시도하면 TypeError
발생하므로 json은 비어 있습니다. 이는 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
키로 직렬화하는 데 영향을 미치지 않습니다.
이는 더 이상 사용되지 않으며 버전 3에서는 효과가 없습니다. 버전 2에서는 dataclasses.dataclass
인스턴스를 직렬화하는 데 필요했습니다. 자세한 내용은 데이터 클래스를 참조하세요.
numpy.ndarray
인스턴스를 직렬화합니다. 자세한 내용은 numpy를 참조하세요.
이는 더 이상 사용되지 않으며 버전 3에서는 효과가 없습니다. 버전 2에서는 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 |
---|---|---|---|
orjson | 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비트 제한을 적용합니다. 그 외에 제한은 Python 표준 라이브러리와 동일한 64비트입니다. 자세한 내용은 int를 참조하세요.
datetime.datetime
인스턴스의 UTC 시간대를 +00:00
대신 Z
로 직렬화합니다.
> >> 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이 제공되는 경우 구현이 충돌하지 않도록 테스트됩니다.
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"))
orjson.loads(b"{}")
입니다. 이는 메모리 사용량이 적고 대기 시간이 짧습니다.
입력은 유효한 UTF-8이어야 합니다.
orjson은 프로세스가 진행되는 동안 맵 키 캐시를 유지합니다. 이렇게 하면 중복 문자열을 방지하여 메모리 사용량이 순 감소합니다. 캐시하려면 키가 최대 64바이트여야 하며 2048개의 항목이 저장됩니다.
전역 인터프리터 잠금(GIL)은 호출 기간 동안 유지됩니다.
잘못된 유형이나 잘못된 JSON이 제공되면 JSONDecodeError
발생합니다. 여기에는 표준 라이브러리에서 허용하지만 유효한 JSON이 아닌 NaN
, Infinity
또는 -Infinity
가 입력에 포함된 경우가 포함됩니다.
배열이나 객체의 조합이 1024레벨 깊이로 반복되면 JSONDecodeError
발생합니다.
JSONDecodeError
는 json.JSONDecodeError
및 ValueError
의 하위 클래스입니다. 이는 표준 라이브러리와의 호환성을 위한 것입니다.
orjson은 기본적으로 dataclasses.dataclass
의 인스턴스를 직렬화합니다. 다른 라이브러리보다 인스턴스를 40~50배 빠르게 직렬화하고 dict
직렬화에 비해 다른 라이브러리에서 볼 수 있는 심각한 속도 저하를 방지합니다.
__slots__
사용하는 데이터 클래스, 고정된 데이터 클래스, 선택적 또는 기본 속성이 있는 데이터 클래스 및 하위 클래스를 포함하여 데이터 클래스의 모든 변형을 전달하는 것이 지원됩니다. __slots__
사용하지 않으면 성능상의 이점이 있습니다.
도서관 | 사전(ms) | 데이터 클래스(ms) | 대 orjson |
---|---|---|---|
orjson | 0.43 | 0.95 | 1 |
JSON | 5.81 | 38.32 | 40 |
이는 기본적으로 JSON, orjson 및 기타 라이브러리의 555KiB 직렬화를 측정하고 dataclasses.asdict()
의 출력을 직렬화하기 위해 default
사용합니다. 이는 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
None
, datetime.timezone.utc
, python3.9+ zoneinfo
모듈의 시간대 인스턴스 또는 타사 pendulum
, pytz
또는 dateutil
/ arrow
라이브러리의 시간대 인스턴스인 tzinfo
있는 인스턴스를 지원합니다.
시간대에 대해서는 표준 라이브러리의 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
옵션을 지정하세요.
UTC("Zulu") 시간을 표시하기 위해 "+00:00" 대신 "Z" 접미사를 사용하려면 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 , json
> >> orjson . dumps ([ float ( "NaN" ), float ( "Infinity" ), float ( "-Infinity" )])
b'[null,null,null]'
> >> json . dumps ([ float ( "NaN" ), float ( "Infinity" ), float ( "-Infinity" )])
'[NaN, Infinity, -Infinity]'
orjson은 기본적으로 64비트 정수를 직렬화 및 역직렬화합니다. 지원되는 범위는 부호 있는 64비트 정수의 최소값(-9223372036854775807)부터 부호 없는 64비트 정수의 최대값(18446744073709551615)까지입니다. 이는 널리 호환되지만 웹 브라우저와 같이 정수에 대해 53비트만 지원하는 구현이 있습니다. 이러한 구현의 경우 53비트 범위를 초과하는 값에 대해 JSONEncodeError
를 발생시키도록 dumps()
구성할 수 있습니다.
> >> 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
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.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
)이어야 하며 지원되는 데이터 유형 중 하나여야 합니다.
ndarray.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 | 105 | 105 | 1 |
JSON | 1,481 | 295 | 14.2 |
이는 (100000, 100)
차원과 numpy.int32
값을 사용하여 numpy.ndarray
에서 JSON 100MiB를 직렬화하는 것을 측정합니다.
도서관 | 지연 시간(밀리초) | RSS 차이(MiB) | 대 orjson |
---|---|---|---|
orjson | 68 | 119 | 1 |
JSON | 684 | 501 | 10.1 |
이는 (100000, 200)
차원과 numpy.bool
값을 사용하여 numpy.ndarray
에서 JSON 105MiB를 직렬화하는 것을 측정합니다.
도서관 | 지연 시간(밀리초) | RSS 차이(MiB) | 대 orjson |
---|---|---|---|
orjson | 50 | 125 | 1 |
JSON | 573 | 398 | 11.5 |
이러한 벤치마크에서 orjson은 기본적으로 직렬화하고 json
default
통해 ndarray.tolist()
직렬화합니다. RSS 열은 직렬화 중 최대 메모리 사용량을 측정합니다. 이는 pynumpy
스크립트를 사용하여 재현할 수 있습니다.
orjson에는 numpy에 대한 설치 또는 컴파일 종속성이 없습니다. 구현은 독립적이며 PyArrayInterface
사용하여 numpy.ndarray
읽습니다.
orjson은 UTF-8 준수에 엄격합니다. 이는 잘못된 UTF-8인 "ud800"과 같은 UTF-16 대체를 직렬화 및 역직렬화하는 표준 라이브러리의 json 모듈보다 더 엄격합니다.
orjson.dumps()
에 유효한 UTF-8을 포함하지 않는 str
이 제공되면 orjson.JSONEncodeError
가 발생합니다. loads()
잘못된 UTF-8을 수신하면 orjson.JSONDecodeError
가 발생합니다.
> >> import orjson , json
> >> orjson . dumps ( ' ud800 ' )
JSONEncodeError : str is not valid UTF - 8 : surrogates not allowed
>> > json . dumps ( ' ud800 ' )
'" \ ud800"'
> >> orjson . loads ( '" \ ud800"' )
JSONDecodeError : unexpected end of hex escape at line 1 column 8 : line 1 column 1 ( char 0 )
> >> 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" ))
'���'
orjson은 uuid.UUID
인스턴스를 RFC 4122 형식(예: "f81d4fae-7dec-11d0-a765-00a0c91e6bf6")으로 직렬화합니다.
> >> import orjson , uuid
> >> 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에 대해 충돌이 발생하지 않고 허용되지 않도록 테스트되었습니다. 웹 서버(다중 프로세스/포크 작업자를 사용하는 Gunicorn) 및 다중 스레드 시 라이브러리 사용을 연습하는 통합 테스트가 있습니다. 또한 ultrajson 라이브러리의 일부 테스트를 사용합니다.
orjson은 비교된 라이브러리 중 가장 정확합니다. 이 그래프는 각 라이브러리가 JSONTestSuite 및 Nativejson-benchmark 테스트의 결합된 342개 JSON 고정 장치를 처리하는 방법을 보여줍니다.
도서관 | 잘못된 JSON 문서가 거부되지 않음 | 역직렬화되지 않은 유효한 JSON 문서 |
---|---|---|
orjson | 0 | 0 |
JSON | 17 | 0 |
이는 모든 라이브러리가 유효한 JSON을 역직렬화하지만 orjson만이 주어진 유효하지 않은 JSON 고정 장치를 올바르게 거부함을 보여줍니다. 오류는 주로 유효하지 않은 문자열과 숫자를 허용함으로써 발생합니다.
위의 그래프는 pycorrectness
스크립트를 사용하여 재현할 수 있습니다.
orjson의 직렬화 및 역직렬화 성능은 표준 라이브러리의 json
보다 일관되게 우수합니다. 아래 그래프는 일반적으로 사용되는 몇 가지 문서를 보여줍니다.
도서관 | 중앙값 대기 시간(밀리초) | 초당 작업 | 상대(대기 시간) |
---|---|---|---|
orjson | 0.1 | 8453 | 1 |
JSON | 1.3 | 765 | 11.1 |
도서관 | 중앙값 대기 시간(밀리초) | 초당 작업 | 상대(대기 시간) |
---|---|---|---|
orjson | 0.5 | 1889년 | 1 |
JSON | 2.2 | 453 | 4.2 |
도서관 | 중앙값 대기 시간(밀리초) | 초당 작업 | 상대(대기 시간) |
---|---|---|---|
orjson | 0.01 | 103693 | 1 |
JSON | 0.13 | 7648 | 13.6 |
도서관 | 중앙값 대기 시간(밀리초) | 초당 작업 | 상대(대기 시간) |
---|---|---|---|
orjson | 0.04 | 23264 | 1 |
JSON | 0.1 | 10430 | 2.2 |
도서관 | 중앙값 대기 시간(밀리초) | 초당 작업 | 상대(대기 시간) |
---|---|---|---|
orjson | 0.3 | 3975 | 1 |
JSON | 3 | 338 | 11.8 |
도서관 | 중앙값 대기 시간(밀리초) | 초당 작업 | 상대(대기 시간) |
---|---|---|---|
orjson | 1.3 | 781 | 1 |
JSON | 4 | 250 | 3.1 |
도서관 | 중앙값 대기 시간(밀리초) | 초당 작업 | 상대(대기 시간) |
---|---|---|---|
orjson | 2.5 | 399 | 1 |
JSON | 29.8 | 33 | 11.9 |
도서관 | 중앙값 대기 시간(밀리초) | 초당 작업 | 상대(대기 시간) |
---|---|---|---|
orjson | 3 | 333 | 1 |
JSON | 18 | 55 | 6 |
위의 내용은 PyPI의 orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
아티팩트를 사용하여 x86-64-v4 시스템의 Fedora 42 컨테이너에서 Python 3.11.10을 사용하여 측정되었습니다. pybench
스크립트를 사용하여 대기 시간 결과를 재현할 수 있습니다.
아마도 최신 Manylinux_x_y 또는 universal2 휠 형식을 지원하려면 pip
버전 20.3 이상으로 업그레이드해야 할 것입니다.
이는 PyPI의 플랫폼에 바이너리 휠(예: ManyLinux)이 없을 때 발생합니다. rustup
이나 패키지 관리자를 통해 Rust를 설치하면 컴파일됩니다.
아니요. 예상되는 유형과 오류 처리 방법 등을 지정하는 스키마가 필요합니다. 이 문제는 이보다 한 단계 높은 데이터 유효성 검사 라이브러리에서 해결됩니다.
str
으로 직렬화됩니까? 아니요. bytes
직렬화된 blob의 올바른 유형입니다.
아니요. orjsonl이 적합할 수 있습니다.
아니요, RFC 8259를 지원합니다.
orjson을 패키징하려면 최소한 Rust 1.72와 maturin 빌드 도구가 필요합니다. 권장되는 빌드 명령은 다음과 같습니다.
maturin build --release --strip
또한 더 빠른 역직렬화 백엔드를 컴파일하기 위해 C 빌드 환경을 갖는 이점도 있습니다. clang 및 LTO를 사용하는 예는 이 프로젝트의 manylinux_2_28
빌드를 참조하세요.
프로젝트 자체 CI는 nightly-2024-11-22
및 stable 1.72에 대해 테스트됩니다. 해당 채널이 주요 변경 사항을 도입할 수 있으므로 야간 버전을 고정하는 것이 좋습니다. nightly를 사용하면 상당한 성능 이점이 있습니다.
orjson은 Linux에서 amd64, aarch64 및 i686에 대해 테스트되었으며 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