Persistance d'objets Python avec Shelve : Guide complet

Decouvrez comment stocker et recuperer facilement vos objets Python avec la bibliotheque Shelve. Apprenez les bonnes pratiques, evitez les pieges courants et maitrisez la persistance de donnees.

Mahmoud DEVO
Mahmoud DEVO
December 27, 2025 7 min read
Persistance d'objets Python avec Shelve : Guide complet

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.

Advertisement

In-Article Ad

Dev Mode

Share this article

Mahmoud DEVO

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