การทำให้เป็นอนุกรม Python - ทำไมต้องดอง?


88

ฉันเข้าใจว่าการดอง Python เป็นวิธี 'จัดเก็บ' Python Object ในลักษณะที่เคารพการเขียนโปรแกรม Object ซึ่งแตกต่างจากเอาต์พุตที่เขียนในไฟล์ txt หรือ DB

คุณมีรายละเอียดเพิ่มเติมหรือข้อมูลอ้างอิงในประเด็นต่อไปนี้:

  • วัตถุดองถูกเก็บไว้ที่ไหน?
  • เหตุใดการดองจึงรักษาการแสดงวัตถุมากกว่าการจัดเก็บใน DB
  • ฉันสามารถดึงวัตถุดองจากเซสชัน Python shell หนึ่งไปยังอีกเซสชันหนึ่งได้หรือไม่
  • คุณมีตัวอย่างที่สำคัญเมื่อการทำให้เป็นอนุกรมมีประโยชน์หรือไม่?
  • การทำให้เป็นอนุกรมกับดองหมายถึง 'การบีบอัดข้อมูล' หรือไม่?

กล่าวอีกนัยหนึ่งฉันกำลังมองหาเอกสารเกี่ยวกับการดอง - Python.doc อธิบายวิธีการใช้ดอง แต่ดูเหมือนจะไม่ได้เจาะลึกลงไปในรายละเอียดเกี่ยวกับการใช้งานและความจำเป็นในการทำให้เป็นอนุกรม


หากต้องการบันทึกสถานะสำหรับการกู้คืนในภายหลังหรือเพื่อแชร์ / คัดลอกวัตถุไปยังรันไทม์ python อื่นจะเป็นสิ่งที่ฉันเดาได้
Synthesizerpatel

13
หลายคำถามของคุณได้รับคำตอบจากบทความของ Wikipedia เกี่ยวกับการทำให้เป็นอนุกรม: en.wikipedia.org/wiki/Serialization
NPE

5
คุณกำลังถามว่าทำไมฉันถึงต้องใช้ Pickle สำหรับการทำให้เป็นอนุกรมใน Python หรืออะไรคือ (จุดประสงค์ของ) การทำให้เป็นอนุกรมหลังจากทั้งหมด? .
moooeeeep

อาจจะเป็นการดีที่จะพูดถึงปัญหาด้านความปลอดภัยด้วยการดอง ตัวอย่างที่สามารถพบได้ในเอกสารและในคำถาม SO จำนวนมากเช่นนี้
djvg

คำตอบ:


99

การดองเป็นวิธีการแปลงออบเจ็กต์ python (list, dict ฯลฯ ) ให้เป็นสตรีมอักขระ แนวคิดก็คือสตรีมอักขระนี้มีข้อมูลทั้งหมดที่จำเป็นในการสร้างวัตถุใหม่ในสคริปต์ python อื่น

ส่วนที่เก็บข้อมูลดองมักจะทำ:

with open('filename', 'wb') as f:
    var = {1 : 'a' , 2 : 'b'}
    pickle.dump(var, f)

ซึ่งจะจัดเก็บคำสั่งในเวอร์ชันดองvarไว้ในไฟล์ "filename" จากนั้นในสคริปต์อื่นคุณสามารถโหลดจากไฟล์นี้เป็นตัวแปรและพจนานุกรมจะถูกสร้างขึ้นใหม่:

with open('filename','rb') as f:
    var = pickle.load(f)

การใช้งานอีกอย่างหนึ่งสำหรับการดองคือถ้าคุณต้องการส่งพจนานุกรมนี้ผ่านเครือข่าย (อาจจะใช้ซ็อกเก็ตหรืออะไรก็ได้) ก่อนอื่นคุณต้องแปลงเป็นสตรีมอักขระจากนั้นจึงส่งผ่านการเชื่อมต่อซ็อกเก็ตได้

นอกจากนี้ยังไม่มี "การบีบอัด" ที่จะพูดถึงที่นี่ ... เป็นเพียงวิธีการแปลงจากการแสดงหนึ่ง (ใน RAM) เป็นอีกวิธีหนึ่ง (ใน "ข้อความ")

About.com มีการแนะนำที่ดีของดองที่นี่


2
ปกติใครจะทำwith open('filename') as f: ...
moooeeeep

3
นอกจากนี้คุณจะต้องทำมิwith open(filename, 'wb') as f: ...ฉะนั้นคุณจะไม่สามารถเขียนลงในไฟล์ได้
Tim Pietzcker

ขอบคุณ !! สิ่งนี้เกี่ยวกับการจัดการการคงอยู่ของ Python นั้นดีที่นี่
kiriloff

1
โดยทั่วไปไม่ควรใช้pickleในการส่งพจนานุกรมผ่านเครือข่าย (json น่าจะดีกว่าที่นี่) แม้ว่าในบางกรณีอาจมีประโยชน์เช่นmultiprocessingโมดูล
jfs

@Tim Pietzcker: protocol=0(ค่าเริ่มต้นบน Python2.x) สามารถใช้ได้กับไฟล์ที่เปิดในโหมดข้อความ
jfs

36

การดองเป็นสิ่งที่จำเป็นอย่างยิ่งสำหรับการประมวลผลแบบกระจายและแบบขนาน

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

ในการทำเช่นนี้ฉันใช้ผักชีลาวซึ่งสามารถทำให้เป็นอนุกรมได้เกือบทุกอย่างใน python Dill ยังมีเครื่องมือดีๆสำหรับช่วยให้คุณเข้าใจว่าอะไรเป็นสาเหตุให้การดองของคุณล้มเหลวเมื่อรหัสของคุณล้มเหลว

และใช่ผู้คนใช้การเลือกเพื่อบันทึกสถานะของการคำนวณหรือเซสชันipythonของคุณหรืออะไรก็ตาม คุณยังสามารถขยาย Pickle's Pickler และ UnPickler เพื่อทำการบีบอัดbz2หรือgzipถ้าคุณต้องการ


0

ฉันคิดว่ามันมีประโยชน์อย่างยิ่งกับคลาสแบบกำหนดเองที่มีขนาดใหญ่และซับซ้อน ในตัวอย่างเฉพาะที่ฉันกำลังนึกถึง "การรวบรวม" ข้อมูล (จากฐานข้อมูล) เพื่อสร้างคลาสนั้นเป็นการต่อสู้ไปครึ่งหนึ่งแล้ว จากนั้นข้อมูลที่จัดเก็บในคลาสอาจถูกเปลี่ยนแปลงขณะรันไทม์โดยผู้ใช้

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

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


-1

มันคือการทำให้เป็นอนุกรม ใช้ cPickle มันเร็วกว่าของดองมาก

import pickle
##make Pickle File
with open('pickles/corups.pickle', 'wb') as handle:
    pickle.dump(corpus, handle)

#read pickle file
with open('pickles/corups.pickle', 'rb') as handle:
    corpus = pickle.load(handle)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.