shelve — Постоянное хранение объектов Python
Исходный код: 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 полка не может знать, когда изменяется мутабельный элемент постоянного словаря. По умолчанию измененные объекты записываются только при присваивании на полке (см. Пример). Если необязательный параметр writeback установлен в
True, все обращенные элементы также кэшируются в памяти и записываются обратно при вызовеsync()иclose(); это может сделать удобнее изменять мутабельные элементы в постоянном словаре, но, если многие элементы обращаются к памяти, это может потребовать больших объёмов памяти для кэша, и операция закрытия может занять очень много времени, поскольку все доступные элементы записываются обратно (нет способа определить, какие элементы обращаются, или какие из них были фактически изменены).Изменено в версии 3.10:
pickle.DEFAULT_PROTOCOLтеперь используется в качестве стандартного протокола pickle.Изменено в версии 3.11: Принимает объект, подобный пути в качестве имени файла.
Примечание
Не полагайтесь на автоматическое закрытие полки; всегда явно вызывайте
close(), когда она больше не нужна, или используйтеshelve.open()как менеджер контекста:with shelve.open('spam') as db: db['eggs'] = 'eggs'
Предупреждение
Поскольку модуль shelve использует модуль pickle, загрузка полки из ненадежного источника небезопасна. Как и при работе с pickle, загрузка полки может выполнить произвольный код.
Объекты Shelf поддерживают большинство методов и операций, поддерживаемых словарями (кроме копирования, конструкторов и операторов | и |=). Это облегчает переход от сценариев, основанных на словарях, к сценариям, требующим постоянного хранения.
Поддерживаются два дополнительных метода:
-
Shelf.sync() -
Записывает обратно все элементы в кэше, если полка была открыта с параметром writeback, установленным в
True. Также очищает кэш и синхронизирует постоянный словарь на диске, если это возможно. Это происходит автоматически при закрытии полки с помощьюclose().
-
Shelf.close() -
Синхронизирует и закрывает постоянный объект dict. Операции с закрытой полкой завершатся ошибкой
ValueError.
См. также
Рецепт постоянного словаря с широко поддерживаемыми форматами хранения и скоростью, сопоставимой с собственными словарями.
Ограничения
- Выбор модуля базы данных (например,
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 — кодировка, используемая для кодирования ключей перед их использованием с основным словарем.
Объект
Shelfтакже может использоваться как менеджер контекста, в этом случае он будет автоматически закрыт при завершении блокаwith.Изменено в версии 3.2: Добавлен параметр keyencoding; ранее ключи всегда кодировались в UTF-8.
Изменено в версии 3.4: Добавлена поддержка менеджеров контекста.
Изменено в версии 3.10:
pickle.DEFAULT_PROTOCOLтеперь используется в качестве стандартного протокола pickle.
-
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 вместо объекта dict. Базовый файл будет открыт с помощью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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/shelve.html