Python - Serialization

Serialization in Python

Serialization đề cập đến quá trình chuyển đổi một đối tượng thành định dạng có thể dễ dàng lưu trữ, truyền tải hoặc tái tạo sau này. Trong Python, điều này bao gồm việc chuyển đổi các cấu trúc dữ liệu phức tạp, chẳng hạn như đối tượng hoặc từ điển, thành một luồng byte.

Why Do We Use Serialization?

Serialization cho phép dữ liệu được dễ dàng lưu trữ vào đĩa hoặc truyền qua mạng, và sau đó được tái tạo trở lại dạng ban đầu của nó. Nó rất quan trọng cho các tác vụ như lưu trạng thái trò chơi, lưu trữ sở thích của người dùng, hoặc trao đổi dữ liệu giữa các hệ thống khác nhau.

Serialization Libraries in Python

Python cung cấp nhiều thư viện cho việc tuần tự hóa, mỗi thư viện có những ưu điểm riêng. Dưới đây là cái nhìn tổng quan chi tiết về một số thư viện tuần tự hóa thường được sử dụng trong Python −

  • Pickle − Đây là mô-đun tích hợp sẵn của Python để tuần tự hóa và giải tuần tự hóa các đối tượng Python. Nó rất đơn giản để sử dụng nhưng cụ thể cho Python và có thể có những vấn đề về bảo mật nếu được sử dụng với dữ liệu không đáng tin cậy.

  • JSON − JSON (JavaScript Object Notation) là một định dạng trao đổi dữ liệu nhẹ, dễ đọc và dễ phân tích. Nó lý tưởng cho các API web và giao tiếp đa nền tảng.

  • YAML − YAML: YAML (YAML không phải là ngôn ngữ đánh dấu) là một tiêu chuẩn tuần tự hóa dữ liệu dễ đọc cho con người, cũng như dễ cho cả con người và máy móc đọc và viết. Nó hỗ trợ các cấu trúc dữ liệu phức tạp và thường được sử dụng trong các tệp cấu hình.

Serialization Using Pickle Module

Mô-đun pickle trong Python được sử dụng để tuần tự hóa và giải tuần tự hóa các đối tượng. Tuần tự hóa, còn được gọi là pickling , liên quan đến việc chuyển đổi một đối tượng Python thành một luồng byte, sau đó có thể được lưu trữ trong một tệp hoặc truyền qua mạng.

Deserialization, hoặc unpickling , là quá trình ngược lại, chuyển đổi dòng byte trở lại thành một đối tượng Python.

Serializing an Object

Chúng ta có thể tuần tự hóa một đối tượng bằng cách sử dụng hàm dump() và ghi nó vào một tệp. Tệp phải được mở ở chế độ ghi nhị phân ('wb').

Example

Trong ví dụ sau, một từ điển được tuần tự hóa và ghi vào một tệp có tên là "data.pkl" −

import pickle

data = {'name': 'Alice', 'age': 30, 'city': 'New York'}

# Open a file in binary write mode
with open('data.pkl', 'wb') as file:
   # Serialize the data and write it to the file
   pickle.dump(data, file)
   print ("File created!!")   

Khi đoạn mã trên được thực thi, biểu diễn byte của đối tượng từ điển sẽ được lưu trữ trong tệp data.pkl.

Deserializing an Object

Để giải tuần tự hóa hoặc unpickle đối tượng, bạn có thể sử dụng hàm load(). Tệp phải được mở ở chế độ đọc nhị phân ('rb') như được hiển thị bên dưới −

import pickle

# Open the file in binary read mode
with open('data.pkl', 'rb') as file:
   # Deserialize the data
   data = pickle.load(file)
print(data)

Điều này sẽ đọc luồng byte từ "data.pkl" và chuyển đổi nó trở lại thành từ điển gốc như được hiển thị dưới đây −

{'name': 'Alice', 'age': 30, 'city': 'New York'}

Pickle Protocols

Các giao thức là các quy ước được sử dụng trong việc xây dựng và giải cấu trúc các đối tượng Python từ/dữ liệu nhị phân.

Mô-đun pickle hỗ trợ các giao thức tuần tự hóa khác nhau, với các giao thức cao hơn thường cung cấp nhiều tính năng hơn và hiệu suất tốt hơn. Hiện tại, mô-đun pickle định nghĩa 6 giao thức khác nhau như được liệt kê dưới đây −

Sr.No. Protocol & Description
1 Protocol version 0 Original "human-readable" protocol backwards compatible with earlier versions.
2 Protocol version 1 Old binary format also compatible with earlier versions of Python.
3 Protocol version 2 Introduced in Python 2.3 provides efficient pickling of new-style classes.
4 Protocol version 3 Added in Python 3.0. recommended when compatibility with other Python 3 versions is required.
5 Protocol version 4 Introduced in Python 3.4. It adds support for very large objects.
6 Protocol version 5 Introduced in Python 3.8. It adds support for out-of-band data.

Bạn có thể chỉ định giao thức bằng cách truyền nó dưới dạng tham số cho hàm pickle.dump().

Để biết phiên bản giao thức cao nhất và mặc định của cài đặt Python của bạn, hãy sử dụng các hằng số sau được định nghĩa trong mô-đun pickle

>>> import pickle
>>> pickle.HIGHEST_PROTOCOL
5
>>> pickle.DEFAULT_PROTOCOL
4

Pickler and Unpickler Classes

Mô-đun pickle trong Python cũng định nghĩa các lớp Pickler Unpickler để kiểm soát chi tiết hơn về quá trình tuần tự hóa và phi tuần tự hóa. Lớp "Pickler" ghi dữ liệu pickle vào một tệp, trong khi lớp "Unpickler" đọc dữ liệu nhị phân từ một tệp và tái tạo đối tượng Python gốc.

Using the Pickler Class

Để tuần tự hóa một đối tượng Python bằng cách sử dụng lớp Pickler, bạn có thể làm theo các bước sau −

from pickle import Pickler

# Open a file in binary write mode
with open("data.txt", "wb") as f:
   # Create a dictionary
   dct = {'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}
   # Create a Pickler object and write the dictionary to the file
   Pickler(f).dump(dct)
   print ("Success!!")

Sau khi thực thi đoạn mã trên, đại diện byte của đối tượng từ điển sẽ được lưu trữ trong tệp "data.txt".

Using the Unpickler Class

Để giải tuần tự dữ liệu từ một tệp nhị phân bằng cách sử dụng lớp Unpickler, bạn có thể làm như sau −

from pickle import Unpickler

# Open the file in binary read mode
with open("data.txt", "rb") as f:
   # Create an Unpickler object and load the dictionary from the file
   dct = Unpickler(f).load()
   # Print the dictionary
   print(dct)

Chúng ta nhận được đầu ra như sau −

{'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}

Pickling Custom Class Objects

Mô-đun pickle cũng có thể tuần tự hóa và giải tuần tự hóa các lớp tùy chỉnh. Định nghĩa lớp phải có sẵn cả khi tuần tự hóa và giải tuần tự hóa.

Example

Trong ví dụ này, một thể hiện của lớp "Person" được tuần tự hóa và sau đó được giải tuần tự, duy trì trạng thái của đối tượng.

import pickle
class Person:
   def __init__(self, name, age, city):
      self.name = name
      self.age = age
      self.city = city

# Create an instance of the Person class
person = Person('Alice', 30, 'New York')

# Serialize the person object
with open('person.pkl', 'wb') as file:
   pickle.dump(person, file)

# Deserialize the person object
with open('person.pkl', 'rb') as file:
   person = pickle.load(file)

print(person.name, person.age, person.city)

Sau khi thực thi đoạn mã trên, chúng ta nhận được đầu ra sau −

Alice 30 New York

Thư viện chuẩn của Python cũng bao gồm mô-đun marshal , được sử dụng cho việc tuần tự hóa nội bộ các đối tượng Python. Không giống như pickle, được thiết kế cho mục đích sử dụng chung, marshal chủ yếu được sử dụng bởi chính Python (ví dụ: để viết các tệp .pyc).

Nói chung, không nên sử dụng cho việc tuần tự hóa đa mục đích do có thể gặp vấn đề tương thích giữa các phiên bản Python.

Using JSON for Serialization

JSON (JavaScript Object Notation) là một định dạng phổ biến cho việc trao đổi dữ liệu. Nó dễ đọc cho con người, dễ viết và độc lập với ngôn ngữ, khiến nó trở nên lý tưởng cho việc tuần tự hóa.

Python cung cấp hỗ trợ tích hợp cho JSON thông qua mô-đun json , cho phép bạn tuần tự hóa và giải tuần tự hóa dữ liệu đến và từ định dạng JSON.

Serialization

Serialization là quá trình chuyển đổi một đối tượng Python thành một chuỗi JSON hoặc ghi nó vào một tệp.

Example: Serialize Data to a JSON String

Trong ví dụ dưới đây, chúng ta sử dụng hàm json.dumps() để chuyển đổi một từ điển Python thành một chuỗi JSON −

import json

# Create a dictionary
data = {"name": "Alice", "age": 25, "city": "San Francisco"}

# Serialize the dictionary to a JSON string
json_string = json.dumps(data)
print(json_string)  

Dưới đây là đầu ra của đoạn mã trên −

{"name": "Alice", "age": 25, "city": "San Francisco"}

Example: Serialize Data and Write to a File

Trong đoạn này, chúng ta sử dụng hàm json.dump() để ghi dữ liệu JSON đã được tuần tự hóa trực tiếp vào một tệp.

import json

# Create a dictionary
data = {"name": "Alice", "age": 25, "city": "San Francisco"}

# Serialize the dictionary and write it to a file
with open("data.json", "w") as f:
   json.dump(data, f)
   print ("Success!!")

Deserialization

Deserialization là quá trình chuyển đổi một chuỗi JSON trở lại thành một đối tượng Python hoặc đọc nó từ một tệp.

Example: Deserialize a JSON String

Trong ví dụ sau, chúng ta sử dụng hàm json.loads() để chuyển đổi một chuỗi JSON trở lại thành một từ điển Python −

import json

# JSON string
json_string = '{"name": "Alice", "age": 25, "city": "San Francisco"}'

# Deserialize the JSON string into a Python dictionary
loaded_data = json.loads(json_string)
print(loaded_data)  

Nó sẽ tạo ra đầu ra sau đây −

{'name': 'Alice', 'age': 25, 'city': 'San Francisco'}

Example: Deserialize Data from a File

Ở đây, chúng ta sử dụng hàm json.load() để đọc dữ liệu JSON từ một tệp và chuyển đổi nó thành một từ điển Python.

import json

# Open the file and load the JSON data into a Python dictionary
with open("data.json", "r") as f:
   loaded_data = json.load(f)
   print(loaded_data)  

Đầu ra thu được như sau −

{'name': 'Alice', 'age': 25, 'city': 'San Francisco'}

Using YAML for Serialization

YAML (YAML Ain't Markup Language) là một tiêu chuẩn tuần tự hóa dữ liệu dễ đọc cho con người, thường được sử dụng cho các tệp cấu hình và trao đổi dữ liệu.

Python hỗ trợ tuần tự hóa và giải tuần tự hóa YAML thông qua gói pyyaml , gói này cần được cài đặt trước như được hiển thị dưới đây −

pip install pyyaml

Example: Serialize Data and Write to a YAML File

Trong ví dụ dưới đây, hàm yaml.dump() chuyển đổi dữ liệu từ từ điển Python thành một chuỗi YAML và ghi nó vào tệp "data.yaml".

Tham số "default_flow_style" đảm bảo rằng đầu ra YAML dễ đọc hơn với định dạng mở rộng.

import yaml

# Create a Python dictionary
data = {"name": "Emily", "age": 35, "city": "Seattle"}

# Serialize the dictionary and write it to a YAML file
with open("data.yaml", "w") as f:
   yaml.dump(data, f, default_flow_style=False)
   print("Success!!")

Example: Deserialize Data from a YAML File

Ở đây, hàm yaml.safe_load() được sử dụng để tải dữ liệu YAML từ "data.yaml" một cách an toàn và chuyển đổi nó thành một từ điển Python (loaded_data) −

Using safe_load() is preferred for security reasons as it only allows basic Python data types and avoids executing arbitrary code from YAML files.
import yaml

# Deserialize data from a YAML file
with open("data.yaml", "r") as f:
   loaded_data = yaml.safe_load(f)
   print(loaded_data)  

Đầu ra được tạo ra như dưới đây -

{'age': 35, 'city': 'Seattle', 'name': 'Emily'}