Spec-Zone.ru › Python 2.7

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

См. также

Module anydbm

Общий интерфейс для баз данных dbm-стиля.

Module bsddb

Интерфейс базы данных BSD db.

Module dbhash

Тонкий слой поверх bsddb, который предоставляет функцию open(), как и другие модули баз данных.

Module dbm

Стандартный интерфейс Unix-баз данных.

Module dumbdbm

Переносимая реализация интерфейса dbm.

Module gdbm

Интерфейс баз данных GNU, основанный на интерфейсе dbm.

Module pickle

Сериализация объектов, используемая модулем shelve.

Module cPickle

Высокопроизводительная версия pickle.

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/2.7/library/shelve.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API