Sök…


Introduktion

Shelve är en pythonmodul som används för att lagra objekt i en fil. Hyllmodulen implementerar långvarig lagring för godtyckliga Python-objekt som kan betas med hjälp av ett ordbordsliknande API. Hyllmodulen kan användas som ett enkelt ihållande lagringsalternativ för Python-objekt när en relationsdatabas är överdödig. Hyllan nås med tangenter, precis som i en ordlista. Värdena plockas in och skrivs till en databas som skapas och hanteras av anydbm.

Anmärkningar

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

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

Varning:

Eftersom shelve stöds av pickle är det osäkert att ladda en hylla från en otillförlitlig källa. Liksom med pickle, kan laddning av en hyllning köra godtycklig kod.

begränsningar

1 . 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 av dbm, om den används - detta innebär att (den inlagda representationen av) de objekt som lagras i databasen borde vara ganska små, och i sällsynta fall kan nyckelkollisioner orsaka databasen till vägra uppdateringar.

2. Hyllmodulen stöder inte samtidigt läs / skrivåtkomst till hyllade objekt. (Flera samtidiga läsåtkomstar är säkra.) När ett program har en hylla öppen för skrivning, bör inget annat program ha det öppet för läsning eller skrivning. Unix-fillåsning kan användas för att lösa detta, men det skiljer sig åt mellan Unix-versioner och kräver kunskap om vilken databasimplementering som används.

Provkod för hyllan

För att hylla ett objekt importerar du först modulen och tilldelar sedan objektvärdet enligt följande:

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

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

Skapa en ny hylla

Det enklaste sättet att använda hyllor är via klassen DbfilenameShelf . Den använder anydbm för att lagra informationen. Du kan använda klassen direkt eller helt enkelt ringa shelf.open () :

import shelve

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

För att komma åt informationen igen öppnar du hyllan och använder den som en ordlista:

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

print existing

Om du kör båda exemplen skript, bör du se:

$ python shelve_create.py
$ python shelve_existing.py

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

Dbm- modulen stöder inte flera applikationer som skriver till samma databas samtidigt. Om du vet att din klient inte kommer att modifiera hyllan kan du säga hyllan att öppna databasen skrivskyddad.

import shelve

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

print existing

Om ditt program försöker ändra databasen medan den öppnas skrivskyddad, genereras ett undantag för åtkomstfel. Undantagstypen beror på databasmodulen som valts av anydbm när databasen skapades.

Skriv tillbaka

Hyllor spårar inte ändringar av flyktiga objekt som standard. Det betyder att om du ändrar innehållet i ett objekt som är lagrat i hyllan måste du uppdatera hyllan uttryckligen genom att lagra objektet igen.

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

I det här exemplet lagras inte ordboken på 'key1' igen, så när hyllan öppnas igen har ändringarna inte bevarats.

$ python shelve_create.py
$ python shelve_withoutwriteback.py

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

För att automatiskt fånga ändringar i flyktiga föremål som lagras i hyllan, öppnar du hyllan med återkoppling aktiverad. Återbaksflaggan gör att hyllan kommer ihåg alla objekt som hämtats från databasen med hjälp av en cache i minnet. Varje cache-objekt skrivs också tillbaka till databasen när hyllan är stängd.

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

Även om det minskar risken för programmeringsfel och kan göra objektets uthållighet mer transparent, är det kanske inte önskvärt att använda återvänt läge i alla situationer. Cachen förbrukar extra minne medan hyllan är öppen, och det kan ta extra tid att pausa för att skriva alla cachade objekt tillbaka till databasen när den är stängd. Eftersom det inte finns något sätt att säga om de cachade objekten har modifierats skrivs de alla tillbaka. Om din applikation läser data mer än den skriver, kommer tillbaka att lägga till mer omkostnader än du kanske vill.

$ 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow