Suche…


Einführung

Shelve ist ein Python-Modul zum Speichern von Objekten in einer Datei. Das Shelve-Modul implementiert einen permanenten Speicher für beliebige Python-Objekte, die mithilfe einer wörterbuchähnlichen API kommissioniert werden können. Das Shelve-Modul kann als einfache persistente Speicheroption für Python-Objekte verwendet werden, wenn eine relationale Datenbank überfordert ist. Das Regal ist wie bei einem Wörterbuch über Schlüssel zugänglich. Die Werte werden in eine Datenbank geschrieben, die von anydbm erstellt und verwaltet wird.

Bemerkungen

Hinweis: Verlassen Sie sich nicht darauf, dass das Regal automatisch geschlossen wird. Rufen Sie close() explizit auf, wenn Sie es nicht mehr benötigen, oder verwenden Sie shelve.open() als Kontextmanager:

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

Warnung:

Da das shelve mit pickle hinterlegt ist, ist es unsicher, ein Regal von einer nicht vertrauenswürdigen Quelle zu laden. Wie bei der Pickle kann das Laden eines Regals beliebigen Code ausführen.

Beschränkungen

1 Die Wahl des zu verwendenden Datenbankpakets (z. B. dbm.ndbm oder dbm.gnu) hängt von der verfügbaren Schnittstelle ab. Daher ist es nicht sicher, die Datenbank direkt mit dbm zu öffnen. Die Datenbank unterliegt (leider) den Einschränkungen von dbm, wenn sie verwendet wird. Dies bedeutet, dass die in der Datenbank gespeicherten Objekte (die angezeigte Darstellung von) relativ klein sein sollten. In seltenen Fällen kann es zu Kollisionen der Datenbank kommen Aktualisierungen ablehnen.

2 .Das Regalmodul unterstützt nicht den gleichzeitigen Lese- / Schreibzugriff auf abgelegte Objekte. (Mehrere gleichzeitige Lesezugriffe sind sicher.) Wenn ein Programm ein Regal zum Schreiben geöffnet hat, sollte es kein anderes Programm zum Lesen oder Schreiben geöffnet haben. Unix-Dateisperren können verwendet werden, um dieses Problem zu lösen. Dies ist jedoch bei den Unix-Versionen unterschiedlich und erfordert Kenntnisse über die verwendete Datenbankimplementierung.

Beispielcode für Regal

Um ein Objekt abzustellen, importieren Sie zuerst das Modul und weisen Sie den Objektwert folgendermaßen zu:

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

Um die Schnittstelle zusammenzufassen (Schlüssel ist eine Zeichenfolge, Daten ist ein beliebiges Objekt):

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

Ein neues Regal erstellen

Die einfachste Möglichkeit, Shelve zu verwenden, ist die Klasse DbfilenameShelf . Es verwendet anydbm, um die Daten zu speichern. Sie können die Klasse direkt verwenden oder einfach shelve.open () aufrufen:

import shelve

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

Um erneut auf die Daten zuzugreifen, öffnen Sie das Regal und verwenden Sie es wie ein Wörterbuch:

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

print existing

Wenn Sie beide Beispielskripts ausführen, sollten Sie Folgendes sehen:

$ python shelve_create.py
$ python shelve_existing.py

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

Das dbm- Modul unterstützt nicht mehrere Anwendungen, die gleichzeitig in dieselbe Datenbank schreiben. Wenn Sie wissen, dass Ihr Client das Regal nicht ändert, können Sie shelve anweisen, die Datenbank schreibgeschützt zu öffnen.

import shelve

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

print existing

Wenn Ihr Programm versucht, die Datenbank zu ändern, während es schreibgeschützt ist, wird eine Zugriffsfehlerausnahme generiert. Der Ausnahmetyp hängt vom Datenbankmodul ab, das von anydbm beim Erstellen der Datenbank ausgewählt wurde.

Schreib zurück

Regale verfolgen standardmäßig keine Änderungen an flüchtigen Objekten. Das heißt, wenn Sie den Inhalt eines Artikels ändern, der im Regal gespeichert ist, müssen Sie das Regal explizit aktualisieren, indem Sie den Artikel erneut speichern.

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()

In diesem Beispiel wird das Wörterbuch unter 'key1' nicht erneut gespeichert. Wenn das Regal erneut geöffnet wird, sind die Änderungen nicht erhalten.

$ python shelve_create.py
$ python shelve_withoutwriteback.py

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

Um Änderungen an flüchtigen Objekten, die im Regal gespeichert sind, automatisch abzufangen, öffnen Sie das Regal mit aktiviertem Rückschreiben. Das Rückschreib-Flag bewirkt, dass das Shelf alle von der Datenbank abgerufenen Objekte mit einem Cache-Speicher im Speicher speichert. Jedes Cache-Objekt wird auch in die Datenbank zurückgeschrieben, wenn das Shelf geschlossen wird.

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()

Obwohl es die Wahrscheinlichkeit von Programmierfehlern verringert und die Objektpersistenz transparenter machen kann, ist der Rückschreibmodus möglicherweise nicht in jeder Situation wünschenswert. Der Cache belegt zusätzlichen Speicher, während das Shelf geöffnet ist, und das Unterbrechen, um jedes zwischengespeicherte Objekt beim Schließen wieder in die Datenbank zu schreiben, kann zusätzliche Zeit in Anspruch nehmen. Da es keine Möglichkeit gibt, festzustellen, ob die zwischengespeicherten Objekte geändert wurden, werden sie alle zurückgeschrieben. Wenn Ihre Anwendung Daten mehr liest als schreibt, erhöht Writeback den Overhead, den Sie möglicherweise benötigen.

$ 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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow