Recherche…


Introduction

Shelve est un module Python utilisé pour stocker des objets dans un fichier. Le module shelve implémente un stockage persistant pour des objets Python arbitraires pouvant être décapés, à l'aide d'une API de type dictionnaire. Le module shelve peut être utilisé comme une option de stockage persistant simple pour les objets Python lorsqu'une base de données relationnelle est excessive. La tablette est accessible par des touches, comme avec un dictionnaire. Les valeurs sont décapées et écrites dans une base de données créée et gérée par anydbm.

Remarques

Remarque: Ne vous fiez pas à la fermeture automatique de la tablette; appelez toujours close() explicitement lorsque vous n'en avez plus besoin, ou utilisez shelve.open() comme gestionnaire de contexte:

with shelve.open('spam') as db:
    db['eggs'] = 'eggs'

Attention:

Étant donné que le module de shelve est soutenu par un pickle , il est impossible de charger une étagère depuis une source non fiable. Comme avec les conserves au vinaigre, charger une étagère peut exécuter du code arbitraire.

Restrictions

1 . Le choix du package de base de données à utiliser (tel que dbm.ndbm ou dbm.gnu) dépend de l’interface disponible. Par conséquent, il n'est pas prudent d'ouvrir la base de données directement à l'aide de dbm. La base de données est également (malheureusement) soumise aux limitations de dbm, si elle est utilisée - cela signifie que (la représentation décapée de) les objets stockés dans la base de données doivent être assez petits, et dans de rares cas refuser les mises à jour

2 .Le module Shelve ne prend pas en charge les accès simultanés en lecture / écriture aux objets mis en attente. (Plusieurs accès en lecture simultanée sont sécurisés.) Lorsqu'un programme a une étagère ouverte pour l'écriture, aucun autre programme ne devrait l'ouvrir pour la lecture ou l'écriture. Le verrouillage de fichier Unix peut être utilisé pour résoudre ce problème, mais cela diffère selon les versions Unix et nécessite des connaissances sur l'implémentation de la base de données utilisée.

Exemple de code pour le rayonnage

Pour mettre un objet en mémoire, commencez par importer le module puis attribuez-lui la valeur suivante:

import shelve 
 database = shelve.open(filename.suffix) 
 object = Object() 
 database['key'] = object 

Pour résumer l'interface (key est une chaîne, data est un objet arbitraire):

import shelve

d = shelve.open(filename)  # open -- file may get suffix added by low-level
                           # library

d[key] = data              # store data at key (overwrites old data if
                           # using an existing key)
data = d[key]              # retrieve a COPY of data at key (raise KeyError
                           # if no such key)
del d[key]                 # delete data stored at key (raises KeyError
                           # if no such key)

flag = key in d            # true if the key exists
klist = list(d.keys())     # a list of all existing keys (slow!)

# as d was opened WITHOUT writeback=True, beware:
d['xx'] = [0, 1, 2]        # this works as expected, but...
d['xx'].append(3)          # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!

# having opened d without writeback=True, you need to code carefully:
temp = d['xx']             # extracts the copy
temp.append(5)             # mutates the copy
d['xx'] = temp             # stores the copy right back, to persist it

# or, d=shelve.open(filename,writeback=True) would let you just code
# d['xx'].append(5) and have it work as expected, BUT it would also
# consume more memory and make the d.close() operation slower.

d.close()                  # close it

Créer une nouvelle étagère

Le moyen le plus simple d’utiliser Shelve est la classe DbfilenameShelf . Il utilise anydbm pour stocker les données. Vous pouvez utiliser la classe directement, ou simplement appeler shelve.open () :

import shelve

s = shelve.open('test_shelf.db')
try:
    s['key1'] = { 'int': 10, 'float':9.5, 'string':'Sample data' }
finally:
    s.close()

Pour accéder à nouveau aux données, ouvrez l'étagère et utilisez-la comme un dictionnaire:

    import shelve
    
    s = shelve.open('test_shelf.db')
    try:
        existing = s['key1']
    finally:
        s.close()

print existing

Si vous exécutez les deux exemples de scripts, vous devriez voir:

$ python shelve_create.py
$ python shelve_existing.py

{'int': 10, 'float': 9.5, 'string': 'Sample data'}

Le module dbm ne prend pas en charge plusieurs applications écrivant simultanément dans la même base de données. Si vous savez que votre client ne modifiera pas l'étagère, vous pouvez demander à shelve d'ouvrir la base de données en lecture seule.

import shelve

s = shelve.open('test_shelf.db', flag='r')
try:
    existing = s['key1']
finally:
    s.close()

print existing

Si votre programme tente de modifier la base de données alors qu'il est ouvert en lecture seule, une exception d'erreur d'accès est générée. Le type d'exception dépend du module de base de données sélectionné par anydbm lors de la création de la base de données.

Réécrire

Les étagères ne suivent pas les modifications apportées aux objets volatils, par défaut. Cela signifie que si vous modifiez le contenu d'un élément stocké dans l'étagère, vous devez mettre à jour l'étagère explicitement en stockant à nouveau l'élément.

import shelve

s = shelve.open('test_shelf.db')
try:
    print s['key1']
    s['key1']['new_value'] = 'this was not here before'
finally:
    s.close()

s = shelve.open('test_shelf.db', writeback=True)
try:
    print s['key1']
finally:
    s.close()

Dans cet exemple, le dictionnaire de 'key1' n'est plus stocké, de sorte que lorsque la tablette est rouverte, les modifications n'ont pas été conservées.

$ python shelve_create.py
$ python shelve_withoutwriteback.py

{'int': 10, 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'float': 9.5, 'string': 'Sample data'}

Pour capturer automatiquement les modifications apportées aux objets volatiles stockés sur l'étagère, ouvrez l'étagère avec l'écriture différée activée. L'indicateur d'écriture différée oblige l'étagère à mémoriser tous les objets extraits de la base de données à l'aide d'un cache en mémoire. Chaque objet de cache est également réécrit dans la base de données lorsque l'étagère est fermée.

import shelve

s = shelve.open('test_shelf.db', writeback=True)
try:
    print s['key1']
    s['key1']['new_value'] = 'this was not here before'
    print s['key1']
finally:
    s.close()

s = shelve.open('test_shelf.db', writeback=True)
try:
    print s['key1']
finally:
    s.close()

Bien que cela réduise le risque d'erreur du programmeur et rend la persistance de l'objet plus transparente, l'utilisation du mode d'écriture différée peut ne pas être souhaitable dans toutes les situations. Le cache consomme de la mémoire supplémentaire lorsque l'étagère est ouverte et la pause pour écrire chaque objet mis en cache dans la base de données à sa fermeture peut prendre plus de temps. Comme il n'y a aucun moyen de savoir si les objets mis en cache ont été modifiés, ils sont tous réécrits. Si votre application lit les données plus qu'elle écrit, l'écriture différée ajoutera plus de données que vous ne le souhaiteriez.

$ python shelve_create.py
$ python shelve_writeback.py

{'int': 10, 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow