shelve — Сохраняемость объектов Python

Исходный код: Lib/shelve.py


«Shelf» - это постоянный объект, похожий на словарь. Разница с базами данных «dbm» заключается в том, что значения (а не ключи!) на shelf могут быть по существу произвольными Python объектами — чем-либо, что модуль pickle может обрабатывать. Он включает большинство классов сущности, рекурсивные типы данных и объекты, содержащие множество общих подобъектов. Ключи - обычные строки.

shelve.open(filename, flag='c', protocol=None, writeback=False)

Открыть постоянный словарь. Указанное имя файла является базовым именем файла для базовой базы данных. В качестве побочного эффекта к имени файла может быть добавлено расширение и может быть создано более одного файла. По умолчанию базовый файл базы данных открывается для чтения и записи. Необязательный параметр flag имеет ту же интерпретацию, что и параметр flag dbm.open().

По умолчанию используется pickles версии 3, чтобы сериализовать значения. Версию протокола pickle можно указать с помощью параметра protocol.

Из-за семантики Python shelf не shelf знать, когда изменяется изменяемая сущность постоянного словаря. По умолчанию измененные объекты записываются только при назначении shelf (см. Пример). Если для необязательного параметра writeback установлено значение True, все доступные записи также кэшируются в памяти и записываются обратно в sync() и close(); это может сделать труднее мутировать изменяемые сущности в постоянном словаре, но, если доступно много статей, он может потреблять огромные объемы памяти для кэш, и это может сделать операцию закрытия очень медленной, так как все доступные статьи записаны обратно (нет способа определить, какие из доступных записей могут изменяться, а какие на самом деле были мутированы).

Примечание

Не полагайтесь на автоматическое закрытие shelf; всегда называйте close() явно, когда вы не будете больше нуждаться в нем или будете использовать shelve.open() в качестве менеджера контекст:

with shelve.open('spam') as db:
    db['eggs'] = 'eggs'

Предупреждение

Поскольку модуль shelve поддерживается функцией pickle, загрузка shelf из ненадежного источника является небезопасной. Как и в случае с pickle, загрузка shelf может выполнять произвольные код.

Объекты shelf поддерживают все методы, поддерживаемые словарями. Это упрощает переход от словарных скриптов к скриптам, требующим постоянного хранения.

Поддерживаются два дополнительных метода:

Shelf.sync()

Написать все записи в ответ в кэш, если shelf была открыта с набором writeback True. Также очистите кэш и синхронизируйте постоянный словарь на диске, если это возможно. Это вызывается автоматически, когда shelf закрыта с помощью close().

Shelf.close()

Синхронизация и закрытие постоянного объекта dict. Операции на закрытой полке завершатся неудачей с ValueError.

См.также

Рецепт постоянного словаря с широко поддерживаемыми форматами хранения и обладанием скоростью родных словарей.

Ограничения

  • Выбором которого пакет базы данных будет используемый (таким как dbm.ndbm или dbm.gnu), зависит, на котором интерфейс доступен. Поэтому открывать базу данных напрямую с помощью dbm небезопасно. База данных также (к сожалению), подвергается ограничениям dbm, если это - используемый —, это означает, что (представление pickled) объекты, хранившие в базе данных, должны быть довольно маленькими, и в ключе редких случаев столкновения могут заставить базу данных отказываться от обновлений.
  • Модуль shelve не поддерживает доступ чтения-записи concurrent к отложенным объектам. (Несколько одновременных доступов для чтения безопасны.) когда программа имеет полку, открытую для записи, ни одна другая программа не должна быть открыта для чтения или записи. Блокировка файлов Unix может быть используемый для решения этой проблемы, но это отличается от версии Unix и требует знаний о реализации базы данных используемый.
class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8')

Подкласс collections.abc.MutableMapping, который хранит pickled значения в объекте dict.

По умолчанию pickles вариантов 3 - используемый, чтобы преобразовать в последовательную форму значения. Версию протокола pickle можно указать с помощью параметра protocol. См. документацию pickle для обсуждения протоколов pickle.

Если параметр writeback равен True, объект будет содержать кэш всех доступных записей и записывать их обратно в dict в момент синхронизации и закрытия. Это позволяет естественные операции с изменяемыми записями, но может потреблять гораздо больше памяти и делать синхронизацию и закрытие занимает много времени.

Параметр keyencoding - это параметр кодировка используемый, который кодирует ключи перед тем, как они будут используемый с лежащими в их основе словарь.

Объект Shelf может также быть используемый как менеджером контекст, в этом случае он будет автоматически закрыт, когда with заблокируют концы.

Изменено в версии 3.2: Добавлен параметр keyencoding; ранее ключи всегда были кодированный в UTF-8.

Изменено в версии 3.4: Добавлена поддержка диспетчера контекст.

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 - файл может получить суффикс, добавленный низкоуровневой
                           # библиотекой

d[key] = data              # хранить данные на ключе (перезаписывает старые данные, если
                           # используя существующий ключ)
data = d[key]              # получить КОПИЮ данных по ключу (поднять KeyError
                           # если нет такого ключа)
del d[key]                 # удалить данные, хранящиеся в ключе (поднимает KeyError
                           # если нет такого ключа)

flag = key in d            # true, если ключ существует
klist = list(d.keys())     # список всех существующих ключей (медленно!)

# as d was opened WITHOUT writeback=True, beware:
d['xx'] = [0, 1, 2]        # это работает как положено, но ...
d['xx'].append(3)          # *это не так!* -- d['xx'] все еще [0, 1, 2]!

# открыв d без обратной записи=True, вам нужно тщательно кодировать:
temp = d['xx']             # извлекает копию
temp.append(5)             # изменяет копию
d['xx'] = temp             # сохраняет копию обратно, чтобы сохранить ее

# или d=shelve.open(filename,writeback=True) позволил бы вам просто код
# d['xx'].append(5) и работать как положено, НО это также
# потребляют больше памяти и замедляют работу d.close().

d.close()                  # закрыть его

См.также

Модуль dbm
Универсальный интерфейс к базам данных стиля dbm.
Модуль pickle
Сериализация объекта используемый shelve.