Spec-Zone.ru › Python 3.13

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

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

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

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

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

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

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

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

Изменено в версии 3.11: Принимает объект-путь в качестве имени файла.

Примечание

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

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

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

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

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

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

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

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

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

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, который принимает имя файла вместо объекта 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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/shelve.html

Spec-Zone.ru

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