shelve — сохранение объектов Python
Исходный код: Lib/shelve.py
«Полка» — это постоянный объект, похожий на словарь. Отличие от баз данных «dbm» заключается в том, что значения (а не ключи!) в полке могут быть практически произвольными объектами Python — всем, с чем может работать модуль pickle. Сюда входят экземпляры большинства классов, рекурсивные типы данных и объекты, содержащие множество общих подчинённых объектов. Ключи — обычные строки.
-
shelve.open(filename, flag='c', protocol=None, writeback=False) -
Открывает постоянный словарь. Указанное имя файла служит базовым именем для лежащей в его основе базы данных. В качестве побочного эффекта к имени файла может быть добавлено расширение, а также может быть создано несколько файлов. По умолчанию файл лежащей в основе базы данных открывается для чтения и записи. Необязательный параметр flag имеет такое же значение, как параметр flag функции
dbm.open().По умолчанию для сериализации значений используются объекты pickle, созданные с помощью
pickle.DEFAULT_PROTOCOL. Версию протокола pickle можно указать с помощью параметра protocol.Из-за семантики Python полка не может определить, когда изменяется изменяемая запись постоянного словаря. По умолчанию изменённые объекты записываются только при присваивании полке (см. Пример). Если необязательному параметру writeback присвоено значение
True, все прочитанные записи также кэшируются в памяти и записываются обратно при вызовеsync()иclose(). Это может упростить изменение изменяемых записей в постоянном словаре, но при обращении ко многим записям кэш может занять огромное количество памяти, а закрытие может занять очень много времени, поскольку все прочитанные записи записываются обратно (невозможно определить, какие из прочитанных записей являются изменяемыми и какие из них действительно были изменены).Изменено в версии 3.10: Теперь в качестве протокола pickle по умолчанию используется
pickle.DEFAULT_PROTOCOL.Изменено в версии 3.11: В качестве имени файла принимается объект, подобный пути.
Примечание
Не рассчитывайте, что полка закроется автоматически; всегда явно вызывайте
close(), когда она больше не нужна, или используйтеshelve.open()в качестве менеджера контекста:with shelve.open('spam') as db: db['eggs'] = 'eggs'
Предупреждение
Поскольку модуль shelve использует pickle, загружать полку из ненадёжного источника небезопасно. Как и при загрузке pickle, загрузка полки может привести к выполнению произвольного кода.
Объекты-полки поддерживают большинство методов и операций, доступных для словарей (за исключением копирования, конструкторов и операторов | и |=). Это упрощает переход от сценариев, использующих словари, к сценариям, которым требуется постоянное хранилище.
Поддерживаются два дополнительных метода:
-
Shelf.sync() -
Записывает обратно все записи кэша, если полка была открыта с параметром writeback, установленным в значение
True. Также очищает кэш и, если возможно, синхронизирует постоянный словарь на диске. Этот метод вызывается автоматически при закрытии полки с помощьюclose().
-
Shelf.close() -
Синхронизирует и закрывает постоянный объект dict. Операции с закрытой полкой завершатся ошибкой
ValueError.
См. также
Рецепт постоянного словаря с широко поддерживаемыми форматами хранения и скоростью обычных словарей.
Ограничения
- Выбор используемого пакета баз данных (например,
dbm.ndbmилиdbm.gnu) зависит от того, какой интерфейс доступен. Поэтому небезопасно открывать базу данных напрямую с помощьюdbm. Кроме того, база данных (к сожалению) подвержена ограничениямdbm, если он используется: это означает, что объекты, хранящиеся в базе данных (в виде представления pickle), должны быть достаточно небольшими, а в редких случаях коллизии ключей могут привести к отказу базы данных от обновлений. - Модуль
shelveне поддерживает одновременный доступ на чтение и запись к объектам в полке. (Несколько одновременных операций чтения безопасны.) Если программа открыла полку для записи, ни одна другая программа не должна открывать её для чтения или записи. Для решения этой проблемы можно использовать блокировку файлов в Unix, однако её реализация различается в разных версиях Unix и требует знания о том, какая реализация базы данных используется. - В macOS
dbm.ndbmможет незаметно повредить файл базы данных при обновлении, что может привести к серьёзным сбоям при попытке чтения из базы данных.
-
class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8') -
Подкласс
collections.abc.MutableMapping, который хранит сериализованные значения в объекте dict.По умолчанию для сериализации значений используются объекты pickle, созданные с помощью
pickle.DEFAULT_PROTOCOL. Версию протокола pickle можно указать с помощью параметра protocol. Обсуждение протоколов pickle см. в документацииpickle.Если параметру writeback присвоено значение
True, объект будет хранить в кэше все прочитанные записи и записывать их обратно в dict при синхронизации и закрытии. Это позволяет естественным образом выполнять операции с изменяемыми записями, но может потребовать намного больше памяти и значительно увеличить время синхронизации и закрытия.Параметр keyencoding задаёт кодировку, используемую для кодирования ключей перед их передачей в лежащий в основе объект dict.
Объект
Shelfтакже можно использовать в качестве менеджера контекста; в этом случае он будет автоматически закрыт по завершении блокаwith.Изменено в версии 3.2: Добавлен параметр keyencoding; ранее ключи всегда кодировались в UTF-8.
Изменено в версии 3.4: Добавлена поддержка менеджера контекста.
Изменено в версии 3.10: Теперь в качестве протокола pickle по умолчанию используется
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, принимающий filename вместо объекта, подобного словарю. Лежащий в основе файл открывается с помощьюdbm.open(). По умолчанию файл создаётся и открывается для чтения и записи. Необязательный параметр flag имеет такое же значение, как и у функцииopen(). Необязательные параметры protocol и writeback имеют такое же значение, как и для классаShelf.
Пример
Кратко подытожим интерфейс (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
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/shelve.html