Table of Contents
Persistance d’objets Python avec Shelve
Introduction
La persistance des donnees est un besoin fondamental dans le developpement d’applications. Que vous construisiez un script de traitement de donnees, une application de bureau ou un outil de configuration, vous aurez souvent besoin de sauvegarder des objets Python entre les executions de votre programme.
Python offre plusieurs solutions pour la persistance : JSON pour les donnees simples, Pickle pour la serialisation binaire, et des bases de donnees comme SQLite pour des besoins plus complexes. Cependant, Shelve se distingue comme une solution elegante qui combine la simplicite d’un dictionnaire Python avec la persistance automatique sur disque.
Shelve utilise en interne le module dbm pour le stockage et pickle pour la serialisation des objets. Cette combinaison vous permet de stocker pratiquement n’importe quel objet Python de maniere transparente, comme si vous utilisiez un simple dictionnaire.
Dans cet article, nous explorerons en profondeur la bibliotheque Shelve, ses cas d’utilisation, ses avantages et ses limites.
Pourquoi choisir Shelve ?
Shelve offre plusieurs avantages par rapport aux autres solutions de persistance :
- Simplicite d’utilisation : Interface identique a un dictionnaire Python
- Objets complexes : Stockage d’objets avec des relations entre eux
- Pas de schema : Aucune definition de structure requise
- Performance : Acces rapide par cle grace au backend dbm
- Bibliotheque standard : Aucune installation supplementaire necessaire
Demarrage rapide avec Shelve
Importer le module
Pour commencer, importez le module Shelve :
import shelve
Ouvrir une base de donnees
Ouvrez un fichier de sauvegarde avec la fonction open() :
# Ouverture en mode lecture/ecriture (par defaut)
database = shelve.open('mon_fichier.db')
# Ouverture en mode lecture seule
database_readonly = shelve.open('mon_fichier.db', flag='r')
# Ouverture avec creation si inexistant
database_create = shelve.open('mon_fichier.db', flag='c')
# Ouverture avec ecrasement du fichier existant
database_new = shelve.open('mon_fichier.db', flag='n')
Sauvegarder et recuperer des objets
L’utilisation est aussi simple qu’un dictionnaire :
import shelve
# Ouverture de la base
with shelve.open('application_data.db') as db:
# Sauvegarder des donnees
db['utilisateur'] = {'nom': 'Jean', 'age': 30, 'email': 'jean@example.com'}
db['configuration'] = {'theme': 'dark', 'langue': 'fr'}
db['compteur'] = 42
# Recuperer des donnees
user = db['utilisateur']
print(f"Utilisateur: {user['nom']}")
# Verifier l'existence d'une cle
if 'configuration' in db:
config = db['configuration']
print(f"Theme: {config['theme']}")
Operations avancees
Interface complete de type dictionnaire
Shelve supporte toutes les operations standard d’un dictionnaire :
import shelve
with shelve.open('donnees.db') as db:
# Stocker plusieurs objets
db['liste'] = [1, 2, 3, 4, 5]
db['tuple'] = ('a', 'b', 'c')
db['ensemble'] = {1, 2, 3}
# Recuperer un objet avec valeur par defaut
valeur = db.get('cle_inexistante', 'valeur_defaut')
# Supprimer un objet
if 'liste' in db:
del db['liste']
# Lister toutes les cles
print("Cles disponibles:", list(db.keys()))
# Lister toutes les valeurs
print("Valeurs:", list(db.values()))
# Iterer sur les paires cle-valeur
for cle, valeur in db.items():
print(f"{cle}: {valeur}")
# Nombre d'elements
print(f"Nombre d'elements: {len(db)}")
Stocker des objets personnalises
Shelve peut stocker vos propres classes :
import shelve
from dataclasses import dataclass
from datetime import datetime
@dataclass
class Article:
titre: str
contenu: str
auteur: str
date_creation: datetime
tags: list
# Creer et sauvegarder un article
article = Article(
titre="Introduction a Python",
contenu="Python est un langage de programmation...",
auteur="Mahmoud DEVO",
date_creation=datetime.now(),
tags=["python", "programmation", "tutoriel"]
)
with shelve.open('blog.db') as db:
db['article_001'] = article
# Recuperer l'article plus tard
with shelve.open('blog.db') as db:
article_recupere = db['article_001']
print(f"Article: {article_recupere.titre}")
print(f"Tags: {', '.join(article_recupere.tags)}")
Mode Writeback pour les modifications en place
Le mode writeback permet de modifier directement les objets mutables :
import shelve
# Sans writeback - les modifications ne sont PAS sauvegardees
with shelve.open('test.db') as db:
db['liste'] = [1, 2, 3]
db['liste'].append(4) # Cette modification est perdue !
with shelve.open('test.db') as db:
print(db['liste']) # Affiche: [1, 2, 3]
# Avec writeback - les modifications SONT sauvegardees
with shelve.open('test.db', writeback=True) as db:
db['liste'] = [1, 2, 3]
db['liste'].append(4) # Cette modification est conservee
with shelve.open('test.db') as db:
print(db['liste']) # Affiche: [1, 2, 3, 4]
Bonnes Pratiques
1. Toujours utiliser le context manager
# Bonne pratique : utiliser 'with'
with shelve.open('data.db') as db:
db['cle'] = 'valeur'
# La base est automatiquement fermee
# A eviter : gestion manuelle
db = shelve.open('data.db')
try:
db['cle'] = 'valeur'
finally:
db.close() # Risque d'oubli !
2. Synchroniser explicitement si necessaire
with shelve.open('important.db') as db:
db['donnees_critiques'] = donnees
db.sync() # Force l'ecriture sur disque immediatement
# Utile avant une operation risquee
3. Gerer les erreurs de cle
with shelve.open('data.db') as db:
# Methode 1 : verification prealable
if 'cle' in db:
valeur = db['cle']
# Methode 2 : valeur par defaut
valeur = db.get('cle', valeur_defaut)
# Methode 3 : try/except
try:
valeur = db['cle']
except KeyError:
valeur = valeur_defaut
4. Organiser vos donnees avec des prefixes
with shelve.open('app.db') as db:
# Utiliser des prefixes pour organiser
db['user:001'] = {'nom': 'Alice'}
db['user:002'] = {'nom': 'Bob'}
db['config:theme'] = 'dark'
db['config:langue'] = 'fr'
# Filtrer par prefixe
users = {k: v for k, v in db.items() if k.startswith('user:')}
Pieges Courants
1. Modifications non sauvegardees sans writeback
# PIEGE : La modification est perdue !
with shelve.open('data.db') as db:
db['dict'] = {'a': 1}
db['dict']['b'] = 2 # Non sauvegarde !
# SOLUTION : Reassigner ou utiliser writeback
with shelve.open('data.db') as db:
temp = db['dict']
temp['b'] = 2
db['dict'] = temp # Reassignation explicite
2. Consommation memoire avec writeback
# ATTENTION : writeback garde tout en memoire
with shelve.open('grosse_base.db', writeback=True) as db:
# Toutes les valeurs accedees restent en memoire
for i in range(100000):
_ = db.get(f'cle_{i}') # Charge en memoire !
# Peut causer des problemes de memoire
# SOLUTION : sync() periodique ou eviter writeback pour grandes bases
3. Fichiers multiples crees par Shelve
# Shelve peut creer plusieurs fichiers selon le backend
# Par exemple : data.db.dir, data.db.bak, data.db.dat
import os
import glob
# Pour supprimer proprement une base Shelve
for fichier in glob.glob('data.db*'):
os.remove(fichier)
4. Problemes de portabilite
# Les fichiers Shelve ne sont pas toujours portables entre systemes
# Le format depend du backend dbm disponible
# Pour la portabilite, specifiez le protocole pickle
with shelve.open('portable.db', protocol=2) as db:
db['data'] = donnees
5. Acces concurrent non supporte
# PIEGE : Shelve n'est pas thread-safe ni process-safe
# Plusieurs processus ne peuvent pas ecrire simultanement
# SOLUTION : Utiliser un verrou ou une base de donnees appropriee
import threading
lock = threading.Lock()
def sauvegarder(cle, valeur):
with lock:
with shelve.open('data.db') as db:
db[cle] = valeur
Cas d’utilisation ideaux
Shelve est particulierement adapte pour :
- Cache applicatif : Stocker des resultats de calculs couteux
- Configuration utilisateur : Preferences et parametres
- Sessions : Donnees de session pour applications de bureau
- Prototypage : Developpement rapide avant migration vers une vraie base
- Scripts : Persistance simple pour scripts et outils
Quand eviter Shelve
Considerez d’autres solutions si vous avez besoin de :
- Acces concurrent multi-processus (utilisez SQLite)
- Requetes complexes (utilisez une base de donnees)
- Portabilite entre systemes (utilisez JSON ou SQLite)
- Donnees volumineuses (utilisez une base de donnees)
- Securite des donnees (Shelve utilise pickle, vulnerable aux donnees malveillantes)
Conclusion
La bibliotheque Shelve est un outil precieux dans l’arsenal du developpeur Python. Sa simplicite d’utilisation, combinee a sa capacite de stocker des objets complexes, en fait une solution ideale pour de nombreux cas d’utilisation.
Les points cles a retenir :
- Utilisez le context manager (
with) pour garantir la fermeture propre - Activez writeback uniquement si vous modifiez des objets mutables en place
- Synchronisez (
sync()) pour les donnees critiques - Evitez Shelve pour les acces concurrents ou les grandes bases de donnees
En suivant les bonnes pratiques presentees dans cet article et en evitant les pieges courants, vous pourrez tirer le meilleur parti de Shelve dans vos projets Python.
N’hesitez pas a explorer la documentation officielle de Shelve pour approfondir vos connaissances.
In-Article Ad
Dev Mode
Mahmoud DEVO
Senior Full-Stack Developer
I'm a passionate full-stack developer with 10+ years of experience building scalable web applications. I write about Vue.js, Node.js, PostgreSQL, and modern DevOps practices.
Enjoyed this article?
Subscribe to get more tech content delivered to your inbox.
Related Articles
Ecrire des fichiers CSV et TSV avec Python : tutoriel complet avec pandas
Apprenez a creer, lire et ecrire des fichiers CSV et TSV en Python avec pandas et le module csv. Guide complet avec exemples pratiques, bonnes pratiques et pieges a eviter.
Recherche de valeurs dans les listes, tuples et dictionnaires Python
Apprenez a rechercher des elements dans les sequences Python : methode index(), mot-cle in, recherche dans les dictionnaires et algorithme bisect pour listes triees.
Expressions Regulieres en Python : Guide Complet pour Maitriser le Module re
Apprenez a maitriser les expressions regulieres en Python avec le module re. Decouvrez comment extraire des donnees, valider des formats, manipuler des chaines et eviter les pieges courants avec des exemples pratiques.