คำว่า object serialization หมายถึงกระบวนการแปลงสถานะของอ็อบเจ็กต์เป็นสตรีมไบต์ (byte stream) หลังจากสร้างแล้ว สตรีมไบต์นี้สามารถเก็บในไฟล์หรือส่งผ่านโซเก็ตได้ อีกด้านหนึ่ง การสร้างอ็อบเจ็กต์กลับจากสตรีมไบต์เรียกว่า deserialization
thuật語ของ Python สำหรับ serialization และ deserialization คือ pickling และ unpickling ตามลำดับ โมดูล pickle ที่มีในไลบรารีมาตรฐานของ Python มีฟังก์ชันสำหรับ serialization (dump() และ dumps()) และ deserialization (load() และ loads())
โมดูล pickle ใช้รูปแบบข้อมูลที่เฉพาะเจาะจงของ Python มาก ดังนั้น โปรแกรมที่ไม่ได้เขียนใน Python อาจไม่สามารถ deserializes ข้อมูลที่เข้ารหัส (pickled) ได้อย่างถูกต้อง นอกจากนี้ ไม่ถือว่าเป็นเรื่องปลอดภัยที่จะ unpickle ข้อมูลจากแหล่งที่ไม่ได้รับการยืนยันตัวตน
โปรโตคอล pickle
โปรโตคอลคือข้อตกลงที่ใช้ในการสร้างและถอดสร้างอ็อบเจ็กต์ Python ไป/มาจากข้อมูลไบนารี ปัจจุบันโมดูล pickle กำหนดโปรโตคอล 5 แบบที่แตกต่างกัน ดังรายการด้านล่าง:
| Protocol version 0 | โปรโตคอล "human-readable" ต้นฉบับ เข้ากันได้กับเวอร์ชันก่อนหน้า |
| Protocol version 1 | รูปแบบไบนารีเก่า เข้ากันได้กับเวอร์ชัน Python ก่อนหน้า |
| Protocol version 2 | เพิ่มใน Python 2.3 ให้ pickling ของ new-style classes มีประสิทธิภาพ |
| Protocol version 3 | เพิ่มใน Python 3.0 แนะนำเมื่อต้องการความเข้ากันได้กับ Python 3 อื่นๆ |
| Protocol version 4 | เพิ่มใน Python 3.4 รองรับอ็อบเจ็กต์ขนาดใหญ่มาก |
เพื่อทราบโปรโตคอลสูงสุดและค่าเริ่มต้นของการติดตั้ง Python ของคุณ ใช้ค่าคงที่ต่อไปนี้ที่กำหนดในโมดูล pickle:
>>> import pickle >>> pickle.HIGHEST_PROTOCOL 4 >>> pickle.DEFAULT_PROTOCOL 3
ตามที่กล่าวไว้ก่อนหน้า ฟังก์ชัน dump() และ load() ของโมดูล pickle ดำเนินการ pickling และ unpickling ข้อมูล Python ฟังก์ชัน dump() เขียนอ็อบเจ็กต์ที่ pickled ลงไฟล์ และฟังก์ชัน load() unpickle ข้อมูลจากไฟล์กลับสู่อ็อบเจ็กต์ Python
โปรแกรมต่อไปนี้ pickle อ็อบเจ็กต์ดิกชันนารีลงในไฟล์ไบนารี:
import pickle
f = open("data.txt", "wb")
dct = {"name": "Ravi", "age": 23, "Gender": "M", "marks": 75}
pickle.dump(dct, f)
f.close()
เมื่อรันโค้ดข้างต้น การแสดงไบต์ของอ็อบเจ็กต์ดิกชันนารีจะถูกเก็บในไฟล์ data.txt
เพื่อ unpickle หรือ deserialize ข้อมูลจากไฟล์ไบนารีกลับสู่ดิกชันนารี ให้รันโปรแกรมต่อไปนี้:
import pickle
f = open("data.txt", "rb")
d = pickle.load(f)
print(d)
f.close()
คอนโซล Python แสดงอ็อบเจ็กต์ดิกชันนารีที่อ่านจากไฟล์:
{'age': 23, 'Gender': 'M', 'name': 'Ravi', 'marks': 75}
โมดูล pickle ยังประกอบด้วยฟังก์ชัน dumps() ที่คืนค่าการแสดงสตริงของข้อมูลที่ pickled:
>>> from pickle import dumps
>>> dct = {"name": "Ravi", "age": 23, "Gender": "M", "marks": 75}
>>> dctstring = dumps(dct)
>>> dctstring
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00Raviq\x02X\x03\x00\x00\x00ageq\x03K\x17X\x06\x00\x00\x00Genderq\x04X\x01\x00\x00\x00Mq\x05X\x05\x00\x00\x00marksq\x06KKu.'
ใช้ฟังก์ชัน loads() เพื่อ unpickle สตริงและได้อ็อบเจ็กต์ดิกชันนารีเดิม:
>>> from pickle import loads
>>> dct = loads(dctstring)
>>> dct
{'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}
โมดูล pickle ยังกำหนดคลาส Pickler และ Unpickler คลาส Pickler เขียนข้อมูล pickle ลงไฟล์ คลาส Unpickler อ่านข้อมูลไบนารีจากไฟล์และสร้างอ็อบเจ็กต์ Python
เพื่อเขียนข้อมูล pickled ของอ็อบเจ็กต์ Python:
from pickle import Pickler
f = open("data.txt", "wb")
dct = {'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}
Pickler(f).dump(dct)
f.close()
เพื่ออ่านข้อมูลกลับโดยการ unpickle ไฟล์ไบนารี:
from pickle import Unpickler
f = open("data.txt", "rb")
dct = Unpickler(f).load()
print(dct)
f.close()
อ็อบเจ็กต์ของชนิดข้อมูลมาตรฐาน Python ทั้งหมดสามารถ pickle ได้ นอกจากนี้ อ็อบเจ็กต์ของคลาสกำหนดเองก็สามารถ pickle และ unpickle ได้:
from pickle import *
class person:
def __init__(self):
self.name = "XYZ"
self.age = 22
def show(self):
print("name:", self.name, "age:", self.age)
p1 = person()
f = open("data.txt", "wb")
dump(p1, f)
f.close()
print("unpickled")
f = open("data.txt", "rb")
p1 = load(f)
p1.show()
ไลบรารี Python ยังมีโมดูล marshal ที่ใช้สำหรับ serialization ภายในของอ็อบเจ็กต์ Python