Serialization (การลำดับข้อมูล) เป็นกระบวนการที่อ็อบเจกต์ถูกแปลงเป็นรูปแบบที่สามารถจัดเก็บ/บันทึก (ในไฟล์หรือ memory buffer) ได้ เพื่อให้เราสามารถ deserialize (ถอดลำดับ) มันภายหลังและกู้คืนเนื้อหา/อ็อบเจกต์ต้นฉบับจากรูปแบบที่ลำดับแล้ว เราจะใช้โมดูล pickle ของ Python เพื่อทำทุกการดำเนินการเหล่านี้
Pickling คืออะไร?
โมดูล pickle ของ Python ใช้สำหรับ serializing และ de-serializing โครงสร้างอ็อบเจกต์ Python กระบวนการที่แปลงอ็อบเจกต์ Python ชนิดใดก็ได้ (list, dict, เป็นต้น) เป็น byte streams (0 และ 1) เรียกว่า pickling หรือ serialization หรือ flattening หรือ marshaling เราสามารถแปลง byte stream (ที่สร้างผ่าน pickling) กลับเป็นอ็อบเจกต์ Python โดยกระบวนการที่เรียกว่า unpickling
เพื่อ pickle อ็อบเจกต์ เราแค่ต้อง −
- Import the pickle
- Call the dumps() function
import pickle class Vehicle: def __init__(self, number_of_doors, color): self.number_of_doors = number_of_doors self.color = color class Car(Vehicle): def __init__(self, color): Vehicle.__init__(self, 5, color) Maruti = Car('Red') print(str.format('My Vehicle Maruti is {0} and has {1} doors', Maruti.color, Maruti.number_of_doors)) pickle_Maruti = pickle.dumps(Maruti) print('Here is my pickled Vehicle: ') print(pickle_Maruti)
ผลลัพธ์
My Vehicle Maruti is Red and has 5 doors Here is my pickled Vehicle: b'\x80\x03c__main__\nCar\nq\x00)\x81q\x01}q\x02(X\x0f\x00\x00\x00number_of_doorsq\x03K\x05X\x05\x00\x00\x00colorq\x04X\x03\x00\x00\x00Redq\x05ub.'
ในตัวอย่างข้างต้น เราสร้าง instance ของคลาส Car และเราได้ pickled มัน แปลง instance รถของเราเป็น array ของ byte ง่ายๆ หลังจาก instance รถของเราถูก pickled เราสามารถจัดเก็บมันในไฟล์ไบนารีหรือใน db field และกู้คืนมันภายหลังเพื่อแปลงกลับชุด byte นี้กลับเป็น階層ของอ็อบเจกต์
หมายเหตุ: หากเราต้องการสร้างไฟล์ด้วย pickled object เราต้องใช้เมธอด dump() แทน dumps()
Unpickling (การถอดลำดับ)
เป็นการดำเนินการย้อนกลับ (ของ pickling) ที่เราเอา binary stream และแปลงกลับเป็น object hierarchy
Unpickling ทำโดยใช้ฟังก์ชัน load() ของโมดูล pickle และคืนค่า object hierarchy เต็มรูปแบบจาก byte stream
ด้านล่างคือ load
import pickle class Vehicle: def __init__(self, number_of_doors, color): self.number_of_doors = number_of_doors self.color = color class Car(Vehicle): def __init__(self, color): Vehicle.__init__(self, 5, color) Maruti = Car('Red') print(str.format('My Vehicle Maruti is {0} and has {1} doors', Maruti.color, Maruti.number_of_doors)) pickle_Maruti = pickle.dumps(Maruti) # ตอนนี้ ลอง unpickle รถ Maruti ของเราสร้าง instance อีกคัน หนึ่งคัน ... unpickle_Maruti Hyundai = pickle.loads(pickle_Maruti) # ตั้งค่าสีอื่นให้ instance ใหม่ของเรา Hyundai.color = 'Black' print(str.format("Hyundai is {0} ", Hyundai.color)) print(str.format("Maruti is {0} ", Maruti.color))
ในตัวอย่างข้างต้น คุณเห็นได้ว่าเรา pickled อ็อบเจกต์รถคันแรก (Maruti) และจากนั้นเรา unpickled มันไปยังตัวแปรอีกตัว (Hyundai) และในความหมายบางอย่าง เรา clone Maruti เพื่อสร้าง Hyundai
ผลลัพธ์
My Vehicle Maruti is Red and has 5 doors Hyundai is Black Maruti is Red
Pickle เทียบกับ JSON
JSON ย่อมาจาก Javascript Object Notation เป็นรูปแบบเบาๆ สำหรับแลกเปลี่ยนข้อมูล และมนุษย์อ่านได้ ข้อได้เปรียบใหญ่ของ JSON เทียบกับ pickle คือมัน standardized และ language-independent มันปลอดภัยและเร็วกว่า pickle มาก
ทางเลือกอื่นสำหรับ pickle คือ cPickle ซึ่งคล้าย pickle มาก แต่เขียนด้วยภาษา C และเร็วกว่า 1000 เท่า คุณสามารถใช้ไฟล์เดียวกันสำหรับ pickle และ cPickle ได้
import json mylist = [2, 4, 5, "ab", "cd", "ef"] print("Here is my list: ", mylist) json_string = json.dumps(mylist ) print("Here is my json encoded object: ", json_string) print ("Here is JSON back to a data structure: ",json.loads(json_string))
ผลลัพธ์
Here is my list: [2, 4, 5, 'ab', 'cd', 'ef'] Here is my json encoded object: [2, 4, 5, "ab", "cd", "ef"] Here is JSON back to a data structure: [2, 4, 5, 'ab', 'cd', 'ef']
ในโค้ดข้างต้น เราเอาอ็อบเจกต์ (my list) ก่อน แล้วใช้เมธอด "dumps" คืนค่าสตริง และจากนั้นโหลด JSON กลับเป็นโครงสร้างข้อมูล เราใช้เมธอด "loads" ที่รับสตริงและแปลงกลับเป็น JSON object data structure