shelve — Python-objektets beständighet

Källkod: Lib/shelve.py


En ”shelf” är ett beständigt, ordboksliknande objekt. Skillnaden mot ”dbm”-databaser är att värdena (inte nycklarna!) i en hylla kan vara i princip godtyckliga Python-objekt — allt som pickle-modulen kan hantera. Detta inkluderar de flesta klassinstanser, rekursiva datatyper och objekt som innehåller massor av delade underobjekt. Nycklarna är vanliga strängar.

shelve.open(filename, flag='c', protocol=None, writeback=False)

Öppnar en persistent ordbok. Det angivna filnamnet är basfilnamnet för den underliggande databasen. Som en bieffekt kan ett tillägg läggas till filnamnet och mer än en fil kan skapas. Som standard öppnas den underliggande databasfilen för läsning och skrivning. Den valfria parametern flag har samma tolkning som parametern flag i dbm.open().

Som standard används pickles som skapats med pickle.DEFAULT_PROTOCOL för att serialisera värden. Versionen av pickle-protokollet kan anges med parametern protocol.

På grund av Pythons semantik kan en hylla inte veta när en mutabel persistent-dictionary-post ändras. Som standard skrivs modifierade objekt endast när de tilldelas hyllan (se Exempel). Om den valfria parametern writeback är inställd på True, kommer alla poster som nås också att cachas i minnet och skrivas tillbaka vid sync() och close(); detta kan göra det enklare att mutera muterbara poster i den beständiga ordboken, men om många poster öppnas kan det förbruka stora mängder minne för cacheminnet, och det kan göra stängningsoperationen mycket långsam eftersom alla öppnade poster skrivs tillbaka (det finns inget sätt att avgöra vilka öppnade poster som är muterbara, eller vilka som faktiskt muterades).

Ändrad i version 3.10: pickle.DEFAULT_PROTOCOL används nu som standardprotokoll för pickle.

Ändrad i version 3.11: Accepterar path-like object för filnamn.

Anteckning

Lita inte på att hyllan stängs automatiskt; anropa alltid close() explicit när du inte behöver det längre, eller använd shelve.open() som en kontexthanterare:

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

Varning

Eftersom modulen shelve backas upp av pickle är det osäkert att ladda en shelf från en icke betrodd källa. Precis som med pickle kan man köra godtycklig kod om man laddar en shelf.

Shelf-objekt stöder de flesta metoder och operationer som stöds av ordböcker (utom kopiering, konstruktörer och operatorerna | och |=). Detta underlättar övergången från ordboksbaserade skript till skript som kräver beständig lagring.

Ytterligare två metoder stöds:

Shelf.sync()

Skriv tillbaka alla poster i cacheminnet om hyllan öppnades med writeback inställd på True. Töm också cacheminnet och synkronisera den beständiga ordboken på disk, om det är möjligt. Detta anropas automatiskt när hyllan stängs med close().

Shelf.close()

Synkroniserar och stänger det beständiga dict-objektet. Åtgärder på en stängd hylla kommer att misslyckas med ett ValueError.

Se även

Persistent ordboksrecept med lagringsformat som stöds i stor utsträckning och med samma hastighet som inbyggda ordböcker.

Begränsningar

  • Valet av vilket databaspaket som ska användas (t.ex. dbm.ndbm eller dbm.gnu) beror på vilket gränssnitt som är tillgängligt. Därför är det inte säkert att öppna databasen direkt med dbm. Databasen är också (tyvärr) föremål för begränsningarna i dbm, om den används — detta innebär att (den inlagda representationen av) de objekt som lagras i databasen bör vara ganska små, och i sällsynta fall kan nyckelkollisioner leda till att databasen vägrar uppdateringar.

  • Modulen shelve stöder inte samtidig läs- och skrivåtkomst till objekt i hyllor. (Flera samtidiga läsåtkomster är säkra.) När ett program har en hylla öppen för skrivning, bör inget annat program ha den öppen för läsning eller skrivning. Unix fillåsning kan användas för att lösa detta, men det skiljer sig mellan olika Unix-versioner och kräver kunskap om den databasimplementering som används.

  • På macOS kan dbm.ndbm i tysthet korrumpera databasfilen vid uppdateringar, vilket kan orsaka hårda krascher när man försöker läsa från databasen.

class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8')

En underklass till collections.abc.MutableMapping som lagrar inlagda värden i dict-objektet.

Som standard används pickles som skapats med pickle.DEFAULT_PROTOCOL för att serialisera värden. Versionen av pickle-protokollet kan specificeras med parametern protocol. Se pickle-dokumentationen för en diskussion om pickle-protokollen.

Om parametern writeback är True, kommer objektet att hålla en cache av alla poster som nås och skriva tillbaka dem till dict vid synkroniserings- och stängningstider. Detta möjliggör naturliga operationer på föränderliga poster, men kan förbruka mycket mer minne och göra att synkronisering och stängning tar lång tid.

Parametern keyencoding är den kodning som används för att koda nycklar innan de används med den underliggande dict.

Ett Shelf-objekt kan också användas som en kontexthanterare, i vilket fall det automatiskt kommer att stängas när with-blocket avslutas.

Ändrad i version 3.2: Parametern keyencoding har lagts till; tidigare var nycklar alltid kodade i UTF-8.

Ändrad i version 3.4: Stöd för kontexthanterare har lagts till.

Ändrad i version 3.10: pickle.DEFAULT_PROTOCOL används nu som standardprotokoll för pickle.

class shelve.BsdDbShelf(dict, protocol=None, writeback=False, keyencoding='utf-8')

En subklass av Shelf som exponerar metoderna first(), next(), previous(), last() och set_location(). Dessa är tillgängliga i tredjepartsmodulen bsddb från pybsddb men inte i andra databasmoduler. Objektet dict som skickas till konstruktören måste stödja dessa metoder. Detta görs i allmänhet genom att anropa en av bsddb.hashopen(), bsddb.btopen() eller bsddb.rnopen(). De valfria parametrarna protocol, writeback och keyencoding har samma tolkning som för klassen Shelf.

class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False)

En subklass av Shelf som accepterar ett filnamn istället för ett diktatliknande objekt. Den underliggande filen öppnas med hjälp av dbm.open(). Som standard kommer filen att skapas och öppnas för både läsning och skrivning. Den valfria parametern flag har samma tolkning som för funktionen open(). De valfria parametrarna protocol och writeback har samma tolkning som för klassen Shelf.

Exempel

För att sammanfatta gränssnittet (key är en sträng, data är ett godtyckligt 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

Se även

Modul dbm

Generiskt gränssnitt för databaser av typen dbm.

Modul pickle

Objektserialisering som används av shelve.