json.dump () และ json.dumps () ใน python แตกต่างกันอย่างไร


131

ฉันค้นหาในเอกสารอย่างเป็นทางการนี้เพื่อค้นหาความแตกต่างระหว่าง json.dump () และ json.dumps () ใน python เป็นที่ชัดเจนว่าเกี่ยวข้องกับตัวเลือกการเขียนไฟล์
แต่อะไรคือความแตกต่างโดยละเอียดระหว่างพวกเขาและในสถานการณ์ใดที่มีข้อได้เปรียบมากกว่าที่อื่น?

คำตอบ:


146

ไม่มีอะไรให้เพิ่มเติมนอกเหนือจากสิ่งที่เอกสารกล่าว ถ้าคุณต้องการที่จะถ่ายโอนข้อมูล JSON เป็นไฟล์ / dump()ซ็อกเก็ตหรืออะไรก็ตามแล้วคุณควรไปด้วย หากคุณต้องการเป็นสตริงเท่านั้น (สำหรับการพิมพ์การแยกวิเคราะห์หรืออะไรก็ตาม) ให้ใช้dumps()(สตริงการถ่ายโอนข้อมูล)

ตามที่กล่าวโดยAntii Haapala ในคำตอบนี้มีความแตกต่างเล็กน้อยเกี่ยวกับensure_asciiพฤติกรรม ส่วนใหญ่เกิดจากการwrite()ทำงานของฟังก์ชันพื้นฐานเนื่องจากมันทำงานเป็นกลุ่มแทนที่จะเป็นสตริงทั้งหมด ตรวจสอบคำตอบของเขาสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนั้น

json.dump()

อนุกรม obj เป็นสตรีมที่จัดรูปแบบ JSON เป็น fp (a .write () - รองรับออบเจ็กต์ที่เหมือนไฟล์

หาก sure_ascii เป็น False บางส่วนที่เขียนถึง fp อาจเป็นอินสแตนซ์ยูนิโคด

json.dumps()

ทำให้ obj เป็นอนุกรมกับ str ที่จัดรูปแบบ JSON

หาก sure_ascii เป็น False ผลลัพธ์อาจมีอักขระที่ไม่ใช่ ASCII และค่าที่ส่งคืนอาจเป็นอินสแตนซ์ Unicode


คุณสามารถแสดงตัวอย่างวิธีการใช้ dump () เพื่อส่งผ่านซ็อกเก็ตได้หรือไม่? ฉันรู้ว่าฉันสามารถใช้ dumps () และ than encode () เพื่อแปลงเป็นไบต์ได้ แต่มีวิธีที่สั้นกว่านี้ไหม
บอย


20

ในการใช้หน่วยความจำและความเร็ว

เมื่อคุณเรียกjsonstr = json.dumps(mydata)มันครั้งแรกจะสร้างสำเนาข้อมูลทั้งหมดของคุณในหน่วยความจำจากนั้นคุณfile.write(jsonstr)จะส่งไปยังดิสก์เท่านั้น ดังนั้นนี่เป็นวิธีที่เร็วกว่า แต่อาจเป็นปัญหาได้หากคุณมีข้อมูลจำนวนมากที่จะบันทึก

เมื่อคุณโทรjson.dump(mydata, file)- โดยไม่มี 's' หน่วยความจำใหม่จะไม่ถูกใช้เนื่องจากข้อมูลจะถูกทิ้งเป็นชิ้น ๆ แต่กระบวนการทั้งหมดช้าลงประมาณ 2 เท่า

ที่มา: ฉันตรวจสอบซอร์สโค้ดของjson.dump()และjson.dumps()และทดสอบทั้งสองตัวแปรที่วัดเวลาด้วยtime.time()และดูการใช้หน่วยความจำใน htop


6

หนึ่งความแตกต่างที่โดดเด่นในหลาม 2คือว่าถ้าคุณกำลังใช้ensure_ascii=False, dumpจะ UTF-8 เข้ารหัสข้อมูลอย่างถูกต้องเขียนลงในแฟ้ม (เว้นแต่คุณจะใช้สาย 8 บิตที่มีอักขระที่ขยายที่ไม่ UTF-8):

dumpsในทางกลับกันensure_ascii=Falseสามารถสร้างstrหรือunicodeขึ้นอยู่กับประเภทที่คุณใช้สำหรับสตริง:

ทำให้อนุกรม obj เป็น str ที่จัดรูปแบบ JSON โดยใช้ตารางการแปลงนี้ หาก ensure_ascii คือ False ผลที่อาจประกอบด้วยอักขระที่ไม่ใช่ ASCII และค่าตอบแทนอาจจะเป็นunicodeตัวอย่าง

(เน้นของฉัน) โปรดทราบว่าอาจยังคงเป็นstrอินสแตนซ์ได้เช่นกัน

unicode.encodeดังนั้นคุณจะไม่สามารถใช้ค่าตอบแทนเพื่อประหยัดโครงสร้างลงในแฟ้มโดยไม่ตรวจสอบรูปแบบที่ถูกส่งกลับและอาจจะเล่นกับ

แน่นอนว่านี่ไม่ใช่ข้อกังวลที่ถูกต้องใน Python 3 อีกต่อไปเนื่องจากไม่มีความสับสน 8 บิต / Unicode อีกต่อไป


สำหรับloadvs loadsให้loadถือว่าไฟล์ทั้งหมดเป็นเอกสาร JSON เดียวดังนั้นคุณจึงไม่สามารถใช้เพื่ออ่านเอกสาร JSON แบบ จำกัด ขึ้นบรรทัดใหม่หลายไฟล์จากไฟล์เดียวได้


ข้อความทั้งหมดที่สร้างขึ้นในออบเจ็กต์สตริง python เป็น Unicode แต่จะปลอดภัยหรือไม่ที่จะคิดแบบนั้น เช่นเมื่อโหลดเนื้อหาจากไฟล์?
JoãoGonçalves

@ JoãoGonçalvesหมายความว่าคุณไม่สามารถผสมข้อมูลไบนารีกับข้อความเพื่อให้ python อนุมัติอย่างเงียบ ๆ เช่นjson.dumps([b'123'])-> TypeError.
Antti Haapala

@ JoãoGonçalvesยังทราบด้วยว่าสตริงในเอกสาร JSON ต้องเป็น Unicodeและต้องอยู่ใน UTF-8, UTF-16 หรือ UTF-32 ใด ๆ ตาม RFC 7159
Antti Haapala

1
ขอบคุณสำหรับคำอธิบาย! เข้าท่า
JoãoGonçalves
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.