Spec-Zone.ru › Python 3.9

shelve — Персистентность объектов Python

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

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

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

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

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

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

Примечание

Не полагайтесь на автоматическое закрытие полки; всегда явно вызывайте 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, если она используется — это означает, что (сериализованное представление) хранимых в базе данных объектов должно быть достаточно маленьким, а в редких случаях коллизии ключей могут привести к отказу базы данных от обновлений.
  • Модуль shelve не поддерживает одновременный доступ для чтения/записи к объектам на полке. (Несколько одновременных операций чтения безопасны.) Когда программа открывает полку для записи, ни другая программа не должна ее открывать для чтения или записи. Заблокировать файлы на Unix можно использовать для решения этой проблемы, но это отличается между версиями Unix и требует знания реализации используемой базы данных.
class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8')

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

По умолчанию для сериализации значений используются версии 3 pickle. Версия протокола 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 вместо объекта 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

См. также

Module dbm

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

Module pickle

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

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

Spec-Zone.ru

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