shelve
— Сохранение объектов Python¶
Kod źródłowy: Lib/shelve.py
„Полиця” — це постійний об’єкт, схожий на словник. Різниця з базами даних „dbm” полягає в тому, що значення (не ключі!) на полиці можуть бути по суті довільними об’єктами Python — будь-чим, що може обробити модуль pickle
. Це включає більшість екземплярів класів, рекурсивних типів даних та об’єктів, що містять багато спільних підоб’єктів. Ключі - звичайні струни.
- shelve.open(filename, flag='c', protocol=None, writeback=False)¶
Відкрийте постійний словник. Вказана назва файлу є базовою назвою файлу базової бази даних. Як побічний ефект до назви файлу може бути додано розширення та може бути створено більше одного файлу. За замовчуванням базовий файл бази даних відкрито для читання та запису. Необов’язковий параметр flag має таку саму інтерпретацію, що й параметр flag
dbm.open()
.По умолчанию пикли, созданные с помощью
pickle.DEFAULT_PROTOCOL
, используются для сериализации значений. Версию протокола Pickle можно указать с помощью параметра protocol.Через семантику Python полиця не може знати, коли змінено запис постійного словника. За замовчуванням змінені об’єкти записуються тільки, коли вони призначені на полицю (див. Przykład). Якщо необов’язковий параметр writeback має значення
True
, усі записи, до яких здійснюється доступ, також кешуються в пам’яті та записуються назад уsync()
іclose()
; це може зробити зручнішим мутацію змінних записів у постійному словнику, але, якщо здійснюється доступ до багатьох записів, це може споживати величезні обсяги пам’яті для кешу, і це може зробити операцію закриття дуже повільною, оскільки всі доступні записи записуються назад ( немає способу визначити, які записи є змінними, а також які з них були змінені).Zmienione w wersji 3.10:
pickle.DEFAULT_PROTOCOL
теперь используется в качестве протокола травления по умолчанию.Zmienione w wersji 3.11: Принимает путеподобный объект в качестве имени файла.
Informacja
Не покладайтеся на автоматичне закриття полиці; завжди викликайте
close()
явно, коли він вам більше не потрібен, або використовуйтеshelve.open()
як контекстний менеджер:with shelve.open('spam') as db: db['eggs'] = 'eggs'
Ostrzeżenie
Оскільки модуль shelve
підтримується pickle
, небезпечно завантажувати полицю з ненадійного джерела. Як і з pickle, завантаження полиці може виконувати довільний код.
Об’єкти полиці підтримують більшість методів і операцій, які підтримуються словниками (крім копіювання, конструкторів і операторів |
і |=
). Це спрощує перехід від сценаріїв на основі словників до сценаріїв, які потребують постійного зберігання.
Підтримуються два додаткові методи:
- Shelf.sync()¶
Записати всі записи в кеші, якщо полицю було відкрито з writeback, встановленим на
True
. Також очистіть кеш і синхронізуйте постійний словник на диску, якщо це можливо. Це викликається автоматично, коли полиця закривається за допомогоюclose()
.
- Shelf.close()¶
Синхронізуйте та закрийте постійний об’єкт dict. Операції на закритій полиці завершаться помилкою з
ValueError
.
Zobacz także
Рецепт постоянного словаря с широко поддерживаемыми форматами хранения и скоростью собственных словарей.
Обмеження¶
Вибір того, який пакет бази даних використовуватиметься (наприклад,
dbm.ndbm
абоdbm.gnu
) залежить від доступного інтерфейсу. Тому небезпечно відкривати базу даних безпосередньо за допомогоюdbm
. База даних також (на жаль) підлягає обмеженнямdbm
, якщо вона використовується — це означає, що (вибране представлення) об’єктів, які зберігаються в базі даних, мають бути досить малими, і в окремих випадках колізії ключів можуть призвести до відмови бази даних в оновленнях.Модуль
shelve
не підтримує одночасний доступ для читання/запису до відкладених об’єктів. (Кілька одночасних доступів для читання є безпечними.) Якщо в програмі є полиця, відкрита для запису, жодна інша програма не повинна мати її відкритою для читання чи запису. Щоб вирішити цю проблему, можна використовувати блокування файлів Unix, але це відрізняється в різних версіях Unix і вимагає знання про використовувану реалізацію бази даних.В macOS
dbm.ndbm
может незаметно повредить файл базы данных при обновлениях, что может привести к серьезным сбоям при попытке чтения из базы данных.
- class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8')¶
Підклас
collections.abc.MutableMapping
, який зберігає обрані значення в об’єкті dict.По умолчанию пикли, созданные с помощью
pickle.DEFAULT_PROTOCOL
, используются для сериализации значений. Версию протокола Pickle можно указать с помощью параметра protocol. См. документациюpickle
для обсуждения протоколов Pickle.Якщо параметр writeback має значення
True
, об’єкт зберігатиме кеш усіх записів, до яких отримав доступ, і записуватиме їх назад у dict під час синхронізації та закриття. Це дозволяє виконувати природні операції над змінними записами, але може споживати набагато більше пам’яті, а синхронізація та закриття триватимуть довго.Параметр keyencoding — це кодування, яке використовується для кодування ключів перед їх використанням із базовим dict.
Об’єкт
Shelf
також можна використовувати як менеджер контексту, і в цьому випадку він буде автоматично закритий, коли блокwith
завершиться.Zmienione w wersji 3.2: Додано параметр keyencoding; раніше ключі завжди кодувалися в UTF-8.
Zmienione w wersji 3.4: Додано підтримку менеджера контексту.
Zmienione w wersji 3.10:
pickle.DEFAULT_PROTOCOL
теперь используется в качестве протокола травления по умолчанию.
- class shelve.BsdDbShelf(dict, protocol=None, writeback=False, keyencoding='utf-8')¶
Подкласс
Shelf
, который предоставляетfirst()
,next()
,previous()
,last()
иset_location()
методы. Они доступны в стороннем модулеbsddb
из pybsddb, но не в других модулях базы данных. Объект dict, передаваемый конструктору, должен поддерживать эти методы. Обычно это достигается путем вызова одной изbsddb.hashopen()
,bsddb.btopen()
илиbsddb.rnopen()
. Необязательные параметры protocol, writeback и keyencoding имеют ту же интерпретацию, что и для классаShelf
.
- class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False)¶
Підклас
Shelf
, який приймає ім’я файлу замість dict-подібного об’єкта. Основний файл буде відкрито за допомогоюdbm.open()
. За замовчуванням файл буде створено та відкрито для читання та запису. Необов’язковий параметр flag має таку саму інтерпретацію, що й функціяopen()
. Необов’язкові параметри protocol і writeback мають таку саму інтерпретацію, що й для класуShelf
.
Przykład¶
Підсумовуючи інтерфейс (key
— це рядок, data
— це довільний об’єкт):
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