Spec-Zone.ru › Python 3.7

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

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

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

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

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

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

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

Примечание

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

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

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

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

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

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

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

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

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

Spec-Zone.ru

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