Spec-Zone.ru › Python 3.10

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

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

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

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

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

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

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

Изменено в версии 3.10: pickle.DEFAULT_PROTOCOL теперь используется в качестве протокола дампов по умолчанию.

Примечание

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

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

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

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

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

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

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

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

Изменено в версии 3.10: pickle.DEFAULT_PROTOCOL теперь используется в качестве протокола дампов по умолчанию.

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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/shelve.html

Spec-Zone.ru

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