orjson เป็นไลบรารี JSON ที่รวดเร็วและถูกต้องสำหรับ Python โดยจะเปรียบเทียบว่าเป็นไลบรารี Python ที่เร็วที่สุดสำหรับ JSON และถูกต้องมากกว่าไลบรารี json มาตรฐานหรือไลบรารีของบริษัทอื่น โดยจะทำให้คลาสข้อมูล, วันที่เวลา, ตัวเลข และอินสแตนซ์ UUID เป็นอนุกรม
orjson.dumps() นั้นเร็วกว่า json
ถึง 10 เท่า ทำให้ประเภททั่วไปและประเภทย่อยเป็นอนุกรม มีพารามิเตอร์ default
สำหรับผู้เรียกเพื่อระบุวิธีทำให้เป็นอนุกรมประเภทตามอำเภอใจ และมีแฟล็กจำนวนหนึ่งควบคุมเอาต์พุต
orjson.loads() นั้นเร็วกว่า json
ถึง 2 เท่า และสอดคล้องกับ UTF-8 และ RFC 8259 อย่างเคร่งครัด ("รูปแบบการแลกเปลี่ยนข้อมูล JavaScript Object Notation (JSON)")
ไลบรารีไม่ได้จัดเตรียมการอ่านและเขียนลงในไฟล์ ไฟล์ JSON ที่คั่นด้วยบรรทัด และอื่นๆ
orjson รองรับ CPython 3.8, 3.9, 3.10, 3.11, 3.12, 3.13 และ 3.14
จำหน่ายล้อ amd64/x86_64, i686/x86, aarch64/armv8, arm7, POWER/ppc64le และ s390x สำหรับ Linux, ล้อ amd64 และ aarch64 สำหรับ macOS และล้อ amd64 และ i686/x86 สำหรับ Windows
orjson ไม่และจะไม่รองรับ PyPy, Python builds แบบฝังสำหรับ Android/iOS หรือตัวแปลย่อย 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
ได้รับการทำให้เป็นอนุกรมตามค่าเริ่มต้น และไม่สามารถปรับแต่งในฟังก์ชัน default
ได้ เว้นแต่จะระบุ option=orjson.OPT_PASSTHROUGH_DATACLASS
อินสแตนซ์ uuid.UUID
จะถูกทำให้เป็นอนุกรมตามค่าเริ่มต้น สำหรับประเภทใดก็ตามที่เป็นอนุกรมในขณะนี้ การใช้งานในฟังก์ชัน default
และตัวเลือกที่เปิดใช้งานสามารถลบออกได้ แต่ไม่จำเป็นต้องเป็น ไม่มีการเปลี่ยนแปลงในการดีซีเรียลไลเซชัน
หากต้องการย้ายจากไลบรารีมาตรฐาน ความแตกต่างที่ใหญ่ที่สุดคือ orjson.dumps
ส่งคืน bytes
และ json.dumps
ส่งคืน str
ผู้ใช้ที่มีอ็อบเจ็กต์ dict
โดยใช้คีย์ที่ไม่ใช่ str
ควรระบุ 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
.TypedDict , datetime.datetime
, datetime.date
, datetime.time
, uuid.UUID
, numpy.ndarray
และ orjson.Fragment
เมนต์ รองรับประเภทที่กำหนดเองผ่าน default
มันทำให้คลาสย่อยเป็นอนุกรมของ str
, int
, dict
, list
, dataclasses.dataclass
และ enum.Enum
มันไม่ได้ทำให้คลาสย่อยของ tuple
เป็นอนุกรมเพื่อหลีกเลี่ยงการทำให้วัตถุ namedtuple
เป็นอนุกรมเป็นอาร์เรย์ หากต้องการหลีกเลี่ยงการทำให้คลาสย่อยเป็นอนุกรม ให้ระบุอ็อพชัน orjson.OPT_PASSTHROUGH_SUBCLASS
ผลลัพธ์เป็นวัตถุ bytes
ที่มี UTF-8
การล็อคล่ามส่วนกลาง (GIL) จะถูกพักไว้ตลอดระยะเวลาการโทร
มันเพิ่ม JSONEncodeError
ในประเภทที่ไม่รองรับ ข้อความยกเว้นนี้อธิบายออบเจ็กต์ที่ไม่ถูกต้องพร้อมข้อความแสดงข้อผิดพลาด Type is not JSON serializable: ...
หากต้องการแก้ไขปัญหานี้ ให้ระบุค่าเริ่มต้น
มันเพิ่ม JSONEncodeError
บน str
ที่มี UTF-8 ที่ไม่ถูกต้อง
โดยจะเพิ่ม JSONEncodeError
ในจำนวนเต็มที่เกิน 64 บิตโดยค่าเริ่มต้น หรือด้วย OPT_STRICT_INTEGER
คือ 53 บิต
โดยจะเพิ่ม JSONEncodeError
หาก dict
มีคีย์ประเภทอื่นที่ไม่ใช่ str
เว้นแต่จะระบุ OPT_NON_STR_KEYS
จะเพิ่ม JSONEncodeError
หากเอาต์พุตของ default
ซ้ำกับการจัดการโดย default
ที่ลึกมากกว่า 254 ระดับ
มันเพิ่ม JSONEncodeError
ในการอ้างอิงแบบวงกลม
มันจะเพิ่ม JSONEncodeError
หาก tzinfo
บนวัตถุ datetime ไม่ได้รับการสนับสนุน
JSONEncodeError
เป็นคลาสย่อยของ TypeError
นี่คือความเข้ากันได้กับไลบรารีมาตรฐาน
หากความล้มเหลวเกิดจากข้อยกเว้นตาม default
ต้น JSONEncodeError
จะเชื่อมโยงข้อยกเว้นเดิมเป็น __cause__
หากต้องการซีเรียลไลซ์คลาสย่อยหรือประเภทที่กำหนดเอง ให้ระบุ default
เป็น callable ที่ส่งคืนประเภทที่รองรับ 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
callable 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):
ห้องสมุด | กะทัดรัด (มิลลิวินาที) | สวย (มิลลิวินาที) | ปะทะ ออร์จสัน |
---|---|---|---|
ออร์จสัน | 0.01 | 0.02 | 1 |
json.json | 0.13 | 0.54 | 34 |
วิธีนี้จะวัดการทำให้ฟิกซ์เจอร์ citm_catalog.json เป็นอนุกรม ซึ่งเป็นกรณีที่แย่ที่สุดเนื่องจากจำนวนการซ้อนและการขึ้นบรรทัดใหม่ ในรูปแบบกะทัดรัด (489KiB) หรือค่อนข้างดี (1.1MiB):
ห้องสมุด | กะทัดรัด (มิลลิวินาที) | สวย (มิลลิวินาที) | ปะทะ ออร์จสัน |
---|---|---|---|
ออร์จสัน | 0.25 | 0.45 | 1 |
json.json | 3.01 | 24.42 | 54.4 |
สิ่งนี้สามารถทำซ้ำได้โดยใช้สคริปต์ pyindent
ทำให้วัตถุเป็นอนุกรม datetime.datetime
โดยไม่มี tzinfo
เป็น UTC สิ่งนี้ไม่มีผลกระทบกับอ็อบเจ็กต์ datetime.datetime
ที่มีการตั้งค่า tzinfo
> >> 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"'
ทำให้คีย์ dict
เป็นอนุกรมประเภทอื่นที่ไม่ใช่ str
สิ่งนี้อนุญาตให้คีย์ 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
serialization ไม่เคารพ OPT_STRICT_INTEGER
ตัวเลือกนี้มีความเสี่ยงในการสร้างคีย์ที่ซ้ำกัน เนื่องจากวัตถุที่ไม่ใช่ str
อาจทำให้เป็นอนุกรมเป็น str
เดียวกันกับคีย์ที่มีอยู่ เช่น {"1": true, 1: false}
คีย์สุดท้ายที่จะแทรกลงใน dict
จะถูกทำให้เป็นอนุกรมเป็นอันดับสุดท้ายและ JSON deserializer จะสันนิษฐานว่าใช้การปรากฏครั้งสุดท้ายของคีย์ (ในข้างต้น 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 ประกอบด้วย list
100 dict
โดยแต่ละ dict
มีคีย์ int
ที่เรียงลำดับแบบสุ่ม 365 คีย์ซึ่งแสดงถึงการประทับเวลาของยุค รวมถึงคีย์ str
หนึ่งคีย์ และค่าสำหรับแต่ละคีย์เป็นจำนวนเต็มตัวเดียว ใน "คีย์ str" คีย์จะถูกแปลงเป็น str
ก่อนการทำให้เป็นอนุกรม และ orjson ยังคงระบุ option=orjson.OPT_NON_STR_KEYS
(ซึ่งค่อนข้างช้ากว่าเสมอ)
ห้องสมุด | ปุ่ม str (มิลลิวินาที) | คีย์ int (มิลลิวินาที) | คีย์ int เรียงลำดับ (ms) |
---|---|---|---|
ออร์จสัน | 0.5 | 0.93 | 2.08 |
json.json | 2.72 | 3.59 |
json ว่างเปล่าเนื่องจากจะทำให้เกิด TypeError
เมื่อพยายามเรียงลำดับก่อนที่จะแปลงคีย์ทั้งหมดเป็น str
สิ่งนี้สามารถทำซ้ำได้โดยใช้สคริปต์ pynonstr
อย่าซีเรียลไลซ์ฟิลด์ microsecond
วินาทีในอินสแตนซ์ datetime.datetime
และ datetime.time
> >> 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"}'
สิ่งนี้จะไม่ส่งผลต่อวันที่และเวลาในคีย์ dict
หากใช้ OPT_NON_STR_KEYS
ส่งผ่านคลาสย่อยของประเภทบิวด์อินเป็น 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'"******"'
สิ่งนี้จะไม่ส่งผลกระทบต่อคลาสย่อยการทำให้เป็นอนุกรมเป็นคีย์ dict
หากใช้ OPT_NON_STR_KEYS
สิ่งนี้เลิกใช้แล้วและไม่มีผลกระทบในเวอร์ชัน 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 ไม่เรียงลำดับและเรียงลำดับ:
ห้องสมุด | ไม่เรียงลำดับ (มิลลิวินาที) | จัดเรียง (มิลลิวินาที) | ปะทะ ออร์จสัน |
---|---|---|---|
ออร์จสัน | 0.11 | 0.3 | 1 |
json.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.
ทำให้เขตเวลา UTC เป็นอนุกรมบนอินสแตนซ์ datetime.datetime
เป็น 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 ที่ทำให้เป็นอนุกรมแล้วในเอกสาร นี่เป็นวิธีที่มีประสิทธิภาพในการรวม JSON blobs จากแคช ฟิลด์ JSONB หรืออ็อบเจ็กต์ซีเรียลไลซ์แยกกัน โดยไม่ต้องทำการดีซีเรียลไลซ์กับอ็อบเจ็กต์ Python ก่อนผ่าน loads()
> >> 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
จะไม่ส่งผลกระทบต่อ Compact Blob และ JSON Blob ที่พิมพ์ออกมาสวยจะไม่ถูกเขียนใหม่เป็น Compact
อินพุตต้องเป็น bytes
หรือ str
และกำหนดให้เป็นอาร์กิวเมนต์ตำแหน่ง
สิ่งนี้จะเพิ่ม orjson.JSONEncodeError
หากกำหนด str
และอินพุตไม่ถูกต้อง UTF-8 มิฉะนั้นจะไม่มีการตรวจสอบความถูกต้องและอาจเขียน 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 ไบต์จึงจะแคชได้ และจัดเก็บได้ 2,048 รายการ
การล็อคล่ามส่วนกลาง (GIL) จะถูกพักไว้ตลอดระยะเวลาการโทร
มันจะเพิ่ม JSONDecodeError
หากได้รับประเภทที่ไม่ถูกต้องหรือ JSON ที่ไม่ถูกต้อง ซึ่งรวมถึงหากอินพุตมี NaN
, Infinity
หรือ -Infinity
ซึ่งไลบรารีมาตรฐานอนุญาต แต่ไม่ใช่ JSON ที่ถูกต้อง
จะเพิ่ม JSONDecodeError
หากการรวมกันของอาร์เรย์หรือวัตถุเรียกซ้ำในระดับลึก 1,024
JSONDecodeError
เป็นคลาสย่อยของ json.JSONDecodeError
และ ValueError
นี่คือความเข้ากันได้กับไลบรารีมาตรฐาน
orjson ทำให้อินสแตนซ์ของ dataclasses.dataclass
เป็นอนุกรมโดยกำเนิด โดยทำให้อินสแตนซ์เป็นอนุกรม 40-50 เท่าเร็วเท่ากับไลบรารีอื่นๆ และหลีกเลี่ยงการชะลอตัวอย่างรุนแรงที่พบในไลบรารีอื่นๆ เมื่อเปรียบเทียบกับการทำให้เป็นอนุกรม dict
รองรับการส่งผ่านคลาสข้อมูลทุกรูปแบบ รวมถึงคลาสข้อมูลที่ใช้ __slots__
คลาสข้อมูลที่แช่แข็ง คลาสที่มีแอตทริบิวต์ทางเลือกหรือค่าเริ่มต้น และคลาสย่อย มีประโยชน์ด้านประสิทธิภาพหากไม่ใช้ __slots__
ห้องสมุด | คำสั่ง (มิลลิวินาที) | คลาสข้อมูล (มิลลิวินาที) | ปะทะ ออร์จสัน |
---|---|---|---|
ออร์จสัน | 0.43 | 0.95 | 1 |
json.json | 5.81 | 38.32 | 40 |
วิธีนี้จะวัดการทำให้เป็นอนุกรม 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.