Module Pickle de Python
En développement Python, nous avons souvent besoin de sauvegarder des objets d'exécution, ou de restaurer l'état précédent après le redémarrage du programme, par exemple :
- Mettre en cache les résultats de calcul sur disque pour éviter les calculs répétés
- Sauvegarder la configuration utilisateur et l'état intermédiaire du programme
- Transmettre des objets complexes entre différents processus Python
pickleLe module est ce que Python fournit pour résoudre ces problèmesSolution officielle intégrée。
Celui de PythonpickleLe module est un module de la bibliothèque standard pour sérialiser et désérialiser des objets Python.
Avant de commencer à utiliser Pickle, vous devez comprendre deux concepts fondamentaux :
- Sérialisation (Pickling) : convertir des objets Python en séquences d'octets
- Désérialisation (Unpickling) : reconvertir des séquences d'octets en objets Python
pickleLe module peut sauvegarder presque tous les objets Python (tels que les listes, les dictionnaires, les instances de classe, etc.) dans des fichiers, ou les transmettre sur le réseau, puis les recharger lorsque cela est nécessaire.
Pourquoi utiliser le module Pickle ?
- Persistance des données: Sauvegarder des objets Python dans des fichiers afin que les données soient encore accessibles après la fermeture du programme.
- Transmission de données: Transmettre des objets Python sur le réseau, par exemple, faire passer des données dans des systèmes distribués.
- Stockage et chargement rapides:
pickleLe module peut gérer efficacement des structures de données complexes et convient aux scénarios qui nécessitent un stockage et un chargement rapides.
Cas d'utilisation typiques de Pickle
pickleIl est très adapté aux scénarios suivants :
- Persistance locale des données
- Sauvegarder et restaurer l'état d'exécution du programme
- Mise en cache des résultats de calcul intermédiaires
- Communication inter-processus en Python (IPC)
- Sauvegarde des modèles d'apprentissage automatique et des données de caractéristiques
Scénarios inadaptés :
- Échange de données entre langages
- Transmission de données d'interface entre le front-end et le back-end
- Désérialisation de sources de données non fiables
Quels objets Pickle prend-il en charge ?
1. Types d'objets pris en charge
| Type | Pris en charge ? |
|---|---|
| int / float / bool / str | Pris en charge |
| list / tuple / dict / set | Pris en charge |
| Aucune | Pris en charge |
| Instances de classes personnalisées | Pris en charge |
| Structures imbriquées | Pris en charge |
Objets non pris en charge ou non recommandés
- Objets fichier ouverts
- socket, connexions aux bases de données
- Ressources du système d'exploitation
- Objets qui dépendent de l'état de l'environnement d'exécution
Importer le module
L'utilisation du module Pickle est très simple, il suffit de l'importer :
import pickle
Utilisation de base du module Pickle
1. Sérialiser des objets
Utiliserpickle.dump()peut sérialiser des objets Python et les enregistrer dans un fichier.
Exemple
# Créer un objet Python
data = {
'name': 'Alice',
'age': 25,
'hobbies': ['reading', 'traveling']
}
# Sérialiser l'objet et l'enregistrer dans un fichier
with open('data.pkl', 'wb') as fichier:
pickle.dump(data, file)
'wb'Indique l'ouverture du fichier en mode écriture binaire.pickle.dump()vadataL'objet est sérialisé et écrit dans le fichier.
2. Désérialiser des objets
Utiliserpickle.load()peut charger et désérialiser des objets Python à partir d'un fichier.
Exemple
# Charger et désérialiser des objets à partir d'un fichier
with open('data.pkl', 'rb') as fichier:
loaded_data = pickle.load(file)
print(loaded_data)
'rb'Indique l'ouverture du fichier en mode lecture binaire.pickle.load()Lire le flux d'octets depuis le fichier et le désérialiser en un objet Python.
3. Sérialiser en chaîne d'octets
Si vous ne souhaitez pas enregistrer dans un fichier, vous pouvez utiliser pickle.dumps() pour sérialiser l'objet en une chaîne d'octets :
Exemple
data = [1, 2, 3, 4, 5]
# Sérialiser en chaîne d'octets
byte_data = pickle.dumps(data)
print(byte_data)
# Sortie similaire à : b'\x80\x04\x95\x0f\x00\x00\x00...'
4. Désérialiser depuis une chaîne d'octets
Utilisez pickle.loads() pour désérialiser des objets à partir d'une chaîne d'octets :
Exemple
byte_data = b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03K\x04K\x05e.'
# Désérialiser depuis une chaîne d'octets
original_data = pickle.loads(byte_data)
print(original_data)
# Sortie : [1, 2, 3, 4, 5]
5. Types d'objets pouvant être sérialisés
Pickle peut sérialiser la plupart des objets Python, notamment :
- Types de données de base : entiers, flottants, chaînes de caractères, booléens, None
- Types de collections : listes, tuples, dictionnaires, ensembles
- Instances de classes personnalisées
- Fonctions et classes (avec certaines limitations)
Exemple
# Sérialiser différents types de données
numbers = [1, 2, 3]
text = "Hello, Pickle"
dictionary = {'key': 'value'}
tuple_data = (1, 2, 3)
set_data = {1, 2, 3}
# Mettre toutes les données dans une liste
all_data = [numbers, text, dictionary, tuple_data, set_data]
# Sérialiser
with open('mixed_data.pkl', 'wb') as f:
pickle.dump(all_data, f)
# Désérialiser
with open('mixed_data.pkl', 'rb') as f:
loaded_data = pickle.load(f)
print(loaded_data)
6. Sérialiser des classes personnalisées
Pickle peut gérer correctement les instances de classes personnalisées :
Exemple
class Student:
def __init__(self, name, age, grade):
self.name = name
self.age = age
self.grade = grade
def __repr__(self):
return f"Student(name={self.name}, age={self.age}, grade={self.grade})"
# Créer une instance
student = Student("Li Si", 20, "Junior")
# Sérialiser
with open('student.pkl', 'wb') as f:
pickle.dump(student, f)
# Désérialiser
with open('student.pkl', 'rb') as f:
loaded_student = pickle.load(f)
print(loaded_student)
# Sortie: Student(name=Li Si, age=20, grade=Junior)
7. Sérialiser plusieurs objets
Vous pouvez appeler pickle.dump() plusieurs fois pour enregistrer plusieurs objets:
Exemple
data1 = {'item': 'apple', 'count': 5}
data2 = ['banana', 'orange', 'grape']
data3 = 42
# Enregistrer plusieurs objets
with open('multiple.pkl', 'wb') as f:
pickle.dump(data1, f)
pickle.dump(data2, f)
pickle.dump(data3, f)
# Lire plusieurs objets (l'ordre doit être cohérent)
with open('multiple.pkl', 'rb') as f:
loaded_data1 = pickle.load(f)
loaded_data2 = pickle.load(f)
loaded_data3 = pickle.load(f)
print(loaded_data1)
print(loaded_data2)
print(loaded_data3)
8. Exemples d'application pratiques
Exemple 1 : Enregistrer et charger la configuration d'un modèle d'apprentissage automatique
Exemple
# Simuler la configuration d'un modèle d'apprentissage automatique
model_config = {
'model_type': 'RandomForest',
'n_estimators': 100,
'max_depth': 10,
'trained_date': '2024-01-13',
'accuracy': 0.95
}
# Enregistrer la configuration
with open('model_config.pkl', 'wb') as f:
pickle.dump(model_config, f)
# Charger la configuration
with open('model_config.pkl', 'rb') as f:
config = pickle.load(f)
print(f"Type de modèle : {config['model_type']}")
print(f"Précision : {config['accuracy']}")
Exemple 2 : Mettre en cache les résultats de calcul
Exemple
import os
def expensive_computation(n):
"""Simuler un calcul chronophage"""
result = sum(i ** 2 for i in range(n))
return result
def compute_with_cache(n, cache_file='cache.pkl'):
# Vérifier si le cache existe
if os.path.exists(cache_file):
with open(cache_file, 'rb') as f:
cache = pickle.load(f)
if n in cache:
print("Lire le résultat depuis le cache")
return cache[n]
else:
cache = {}
# Effectuer le calcul
print("Calcul en cours...")
result = expensive_computation(n)
# Enregistrer dans le cache
cache[n] = result
with open(cache_file, 'wb') as f:
pickle.dump(cache, f)
return result
# Exemple d'utilisation
print(compute_with_cache(1000000)) # La première fois, il calculera
print(compute_with_cache(1000000)) # La deuxième fois, lecture depuis le cache
Remarques sur le module Pickle
- Sécurité:
pickleLe module exécute du code arbitraire lors de la désérialisation, donc ne chargez paspicklede données provenant de sources non fiables, afin d'éviter des attaques malveillantes. - Compatibilité:
pickleLe flux d'octets généré est spécifique à Python, et il peut y avoir des problèmes de compatibilité entre différentes versions de Python. - Performance: Pour de grands ensembles de données,
picklela sérialisation et la désérialisation peuvent être relativement lentes ; vous pouvez envisager d'utiliser des outils de sérialisation plus efficaces, tels quejsonoumsgpack。
Utilisation avancée : sérialisation d'objets personnalisés
pickleLe module prend en charge la sérialisation de classes personnalisées. Par défaut,pickleil enregistre les attributs de l'objet et le nom de la classe. Si vous avez besoin d'une logique de sérialisation plus complexe, vous pouvez implémenter__getstate__()et__setstate__()méthodes traditionnelles.
Exemple
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __getstate__(self):
# Logique de sérialisation personnalisée
return {'name': self.name, 'age': self.age}
def __setstate__(self, state):
# Logique de désérialisation personnalisée
self.name = state['name']
self.age = state['age']
# Créer l'objet et sérialiser
person = Person('Bob', 30)
with open('person.pkl', 'wb') as fichier:
pickle.dump(person, file)
# Désérialiser l'objet
with open('person.pkl', 'rb') as fichier:
loaded_person = pickle.load(file)
print(loaded_person.name, loaded_person.age)
Méthodes courantes du module pickle
| Méthode | Description | Exemple |
|---|---|---|
pickle.dump(obj, file) | Sérialiser un objet et écrire dans un fichier | pickle.dump(data, open('data.pkl', 'wb')) |
pickle.load(file) | Lire à partir d'un fichier et désérialiser un objet | data = pickle.load(open('data.pkl', 'rb')) |
pickle.dumps(obj) | Sérialiser un objet en une chaîne d'octets | bytes_data = pickle.dumps([1, 2, 3]) |
pickle.loads(bytes) | Désérialiser un objet à partir d'une chaîne d'octets | lst = pickle.loads(bytes_data) |
pickle.HIGHEST_PROTOCOL | Version de protocole la plus élevée disponible (attribut) | pickle.dump(..., protocol=pickle.HIGHEST_PROTOCOL) |
pickle.DEFAULT_PROTOCOL | Version de protocole par défaut (attribut, généralement 4) | pickle.dumps(obj, protocol=pickle.DEFAULT_PROTOCOL) |
1. Sérialiser un objet dans un fichier
Exemple
data = {'name': 'Alice', 'age': 25}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
2. Désérialiser depuis un fichier
Exemple
loaded_data = pickle.load(f)
print(loaded_data) # Sortie : {'name': 'Alice', 'age': 25}
3. Sérialiser en chaîne d'octets (transmission réseau/cache)
Exemple
restored_list = pickle.loads(bytes_data)
Versions du protocole du module pickle
| Version du protocole | Description |
|---|---|
| 0 | Format ASCII lisible par l'homme (compatible avec les versions antérieures) |
| 1 | Format binaire (compatible avec les versions antérieures) |
| 2 | Prise en charge optimisée des objets de classe par Python 2.3+ |
| 3 | Protocole par défaut de Python 3.0+ (non pris en charge dans Python 2) |
| 4 | Python 3.4+ prend en charge des objets plus volumineux et davantage de types de données |
| 5 | Python 3.8+ prend en charge l'optimisation de la mémoire et le partage de données |