Spec-Zone.ru › Python 3.14

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

Spec-Zone.ru

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