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 vidsync()
ochclose()
; 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ändshelve.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 medclose()
.
- 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
ellerdbm.gnu
) beror på vilket gränssnitt som är tillgängligt. Därför är det inte säkert att öppna databasen direkt meddbm
. Databasen är också (tyvärr) föremål för begränsningarna idbm
, 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. Sepickle
-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ärwith
-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 metodernafirst()
,next()
,previous()
,last()
ochset_location()
. Dessa är tillgängliga i tredjepartsmodulenbsddb
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 avbsddb.hashopen()
,bsddb.btopen()
ellerbsddb.rnopen()
. De valfria parametrarna protocol, writeback och keyencoding har samma tolkning som för klassenShelf
.
- 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 avdbm.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 funktionenopen()
. De valfria parametrarna protocol och writeback har samma tolkning som för klassenShelf
.
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