shelve — Персистентное хранение объектов Python
Исходный код: Lib/shelve.py
«Шелф» — это персистентный объект, подобный словарю. Различие с базами данных «dbm» заключается в том, что значения (а не ключи!) в шелфе могут быть произвольными объектами Python — всё, что может обработать модуль pickle. Это включает в себя большинство экземпляров классов, рекурсивные типы данных и объекты, содержащие много общих подобъектов. Ключи — это обычные строки.
-
shelve.open(filename, flag='c', protocol=None, writeback=False) -
Открывает персистентный словарь. Указанное имя файла — это базовое имя файла для основной базы данных. В качестве побочного эффекта к имени файла может быть добавлено расширение, и может быть создано несколько файлов. По умолчанию, базовый файл базы данных открывается для чтения и записи. Дополнительный параметр flag интерпретируется так же, как и параметр flag функции
anydbm.open().По умолчанию для сериализации значений используются пикли версии 0. Версия протокола пикла может быть указана с помощью параметра protocol.
Изменено в версии 2.3: Добавлен параметр protocol.
Из-за семантики Python шелф не может знать, когда изменяется мутирующая запись персистентного словаря. По умолчанию изменённые объекты записываются только при присваивании в шелф (см. Пример). Если необязательный параметр writeback установлен в
True, все обращённые к записям кэшируются в памяти и записываются обратно при вызовеsync()иclose(); это может сделать удобнее мутирование изменяемых записей в персистентном словаре, но, если обращаются к многим записям, это может потребовать значительного объёма памяти для кэша, а операция закрытия может занять очень много времени, так как все обращённые записи записываются обратно (нет способа определить, какие записи изменяемые, а также какие из них были фактически изменены).Как и объекты файлов, объекты shelve должны быть закрыты явно, чтобы убедиться, что персистентные данные записаны на диск.
Предупреждение
Так как модуль shelve использует модуль pickle, загружать шелф из ненадежного источника небезопасно. Как и при работе с pickle, загрузка шелфа может привести к выполнению произвольного кода.
Объекты Shelf поддерживают большинство методов, поддерживаемых словарями. Это облегчает переход от скриптов, использующих словари, к скриптам, требующим персистентного хранения.
Обратите внимание, что методы перехода к Python 3 (viewkeys(), viewvalues() и viewitems()) не поддерживаются.
Поддерживаются два дополнительных метода:
-
Shelf.sync() -
Записать все записи в кэше, если шелф был открыт с параметром writeback, установленным в
True. Также очистить кэш и синхронизировать персистентный словарь на диске, если это возможно. Это выполняется автоматически при закрытии шелфа с помощьюclose().
-
Shelf.close() -
Синхронизировать и закрыть персистентный объект dict. Операции с закрытым шелфом завершатся ошибкой
ValueError.
См. также
Рецепт персистентного словаря с широко поддерживаемыми форматами хранения и скоростью, сравнимой с обычными словарями.
1. Ограничения
- Выбор модуля базы данных (например,
dbm,gdbmилиbsddb) зависит от доступного интерфейса. Поэтому открывать базу данных напрямую с помощьюdbmнебезопасно. База данных также (к сожалению) подвержена ограничениям модуляdbm, если он используется — это означает, что (записей пикла) объектов, хранящихся в базе данных, должны быть относительно небольшими, и в редких случаях коллизии ключей могут привести к отказу базы данных от обновлений. - Модуль
shelveне поддерживает одновременный доступ для чтения/записи к объектам в шелфе. (Множественный одновременный доступ для чтения безопасен.) Когда программа открывает шелф для записи, ни одна другая программа не должна иметь его открытым для чтения или записи. Блокировка файлов Unix может быть использована для решения этой проблемы, но это отличается в различных версиях Unix и требует знаний о реализации используемой базы данных.
-
class shelve.Shelf(dict, protocol=None, writeback=False) -
Подкласс
UserDict.DictMixin, который хранит пиклированные значения в объекте dict.По умолчанию для сериализации значений используются пикли версии 0. Версия протокола пикла может быть указана с помощью параметра protocol. См. документацию по
pickleдля обсуждения протоколов пикла.Изменено в версии 2.3: Добавлен параметр protocol.
Если параметр writeback равен
True, объект будет содержать кэш всех обращённых записей и запишет их обратно в dict при вызовах sync и close. Это позволяет проводить естественные операции с изменяемыми записями, но может занимать значительно больше памяти и замедлять вызовы sync и close.
-
class shelve.BsdDbShelf(dict, protocol=None, writeback=False) -
Подкласс
Shelf, который предоставляетfirst(),next(),previous(),last()иset_location(), которые доступны в модулеbsddb, но недоступны в других модулях баз данных. Объект dict, переданный конструктору, должен поддерживать эти методы. Это обычно достигается вызовом одной из функцийbsddb.hashopen(),bsddb.btopen()илиbsddb.rnopen(). Необязательные параметры protocol и writeback имеют то же значение, что и для классаShelf.
-
class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False) -
Подкласс
Shelf, который принимает имя файла вместо объекта dict. Базовый файл будет открыт с помощьюanydbm.open(). По умолчанию файл будет создан и открыт как для чтения, так и для записи. Необязательный параметр flag интерпретируется так же, как и для функцииopen(). Необязательные параметры protocol и writeback имеют то же значение, что и для классаShelf.
2. Пример
Для краткого описания интерфейса (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 = d.has_key(key) # true if the key exists
klist = d.keys() # a list of all existing keys (slow!)
# as d was opened WITHOUT writeback=True, beware:
d['xx'] = range(4) # this works as expected, but...
d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)!
# 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
См. также
-
Moduleanydbm -
Общий интерфейс для баз данных
dbm-стиля. -
Modulebsddb -
Интерфейс базы данных BSD
db. -
Moduledbhash -
Тонкий слой поверх
bsddb, который предоставляет функциюopen(), как и другие модули баз данных. -
Moduledbm -
Стандартный интерфейс Unix-баз данных.
-
Moduledumbdbm -
Переносимая реализация интерфейса
dbm. -
Modulegdbm -
Интерфейс баз данных GNU, основанный на интерфейсе
dbm. -
Modulepickle -
Сериализация объектов, используемая модулем
shelve. -
ModulecPickle -
Высокопроизводительная версия
pickle.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/2.7/library/shelve.html