Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Pickle trong Python: Serialize và Deserialize đối tượng

Pickle chuyển đổi đối tượng Python (list, dict, class instance...) thành byte stream (serialization) và ngược lại (deserialization/unpickling). Dùng để lưu trữ, truyền dữ liệu giữa các process/server.

Cơ bản

import pickle

# Pickle (dumps → bytes, dump → file)
data = {'name': 'Zack', 'age': 25}
pickled = pickle.dumps(data)      # bytes
pickle.dump(data, open('data.pkl', 'wb'))  # ghi file

# Unpickle
data2 = pickle.loads(pickled)     # từ bytes
data3 = pickle.load(open('data.pkl', 'rb')) # từ file

Ví dụ: Pickle List

import pickle

mylist = ['a', 'b', 'c', 'd']
with open('datafile.txt', 'wb') as fh:
    pickle.dump(mylist, fh)

# Unpickle
with open('datafile.txt', 'rb') as f:
    emp = pickle.load(f)
print(emp)  # ['a', 'b', 'c', 'd']

Ví dụ: Pickle Dictionary

EmpID = {1: "Zack", 2: "53050", 3: "IT", 4: "38", 5: "Flipkart"}
with open("EmpID.pickle", "wb") as f:
    pickle.dump(EmpID, f)

with open("EmpID.pickle", "rb") as f:
    print(pickle.load(f))
# {1: 'Zack', 2: '53050', 3: 'IT', 4: '38', 5: 'Flipkart'}

Pickle Class Instance

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __repr__(self):
        return f'Person({self.name}, {self.age})'

p = Person('Alice', 30)
with open('person.pkl', 'wb') as f:
    pickle.dump(p, f)

with open('person.pkl', 'rb') as f:
    p2 = pickle.load(f)
print(p2)  # Person(Alice, 30)

Exception thường gặp

Pickle.PicklingErrorĐối tượng không hỗ trợ pickle
Pickle.UnpicklingErrorFile corrupt / dữ liệu xấu
EOFErrorĐọc hết file mà chưa xong object

Ưu / Nhược điểm

ƯuĐơn giản, hỗ trợ hầu hết object Python, nhị phân compact
NhượcChỉ Python đọc được, KHÔNG AN TOÀN với dữ liệu không tin cậy (RCE)

⚠️ Cảnh báo bảo mật

Không bao giờ unpickle dữ liệu từ nguồn không tin cậy. Pickle có thể thực thi code tùy ý khi deserialize (RCE - Remote Code Execution). Dùng json cho dữ liệu không tin cậy.

Protocol version

pickle.dump(obj, f, protocol=pickle.HIGHEST_PROTOCOL)  # Tối ưu size/speed