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-объекты, созданные с помощью pickle.DEFAULT_PROTOCOL. Версию протокола pickle можно указать с помощью параметра protocol.

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

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

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

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

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

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

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

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

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

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

Изменено в версии 3.10: Теперь в качестве протокола pickle по умолчанию используется 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 вместо объекта, подобного словарю. Базовый файл открывается с помощью 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–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/shelve.html

Spec-Zone.ru

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