Spec-Zone.ru › Python 3.12

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 теперь используется в качестве протокола пикли по умолчанию.

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

Примечание

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

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

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

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

Объекты шелфа поддерживают большинство методов и операций, поддерживаемых словарями (кроме копирования, конструкторов и операторов | и |=). Это упрощает переход от скриптов, основанных на словарях, к скриптам, требующим постоянного хранения.

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

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. Версия протокола пикла может быть указана с помощью параметра protocol. Обратитесь к документации по 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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/shelve.html

Spec-Zone.ru

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