Shelve module in python

shelve — Сохраняемость Python объектов¶

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

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

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

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

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

Читайте также:  List to string array python

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

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

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

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

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

Записывает все записи в кэш, если шелф был открыт с writeback, установленным на True . Также очистить кеш и синхронизировать постоянный словарь на диске, если это возможно. Вызывается автоматически, когда шелф закрывается с помощью close() .

Синхронизировать и закрыть постоянный объект dict. Операции на закрытом шелфе завершатся ошибкой с ValueError .

Рецепт постоянного словаря с широко поддерживаемыми форматами хранения и скоростью собственных словарей.

Ограничения¶

  • Выбор того, какой пакет базы данных будет использоваться (например, dbm.ndbm или dbm.gnu ), зависит от того, какой интерфейс доступен. Поэтому открывать базу данных напрямую с помощью dbm небезопасно. База данных также (к сожалению) подчиняется ограничениям dbm , если она используется, это означает, что (пиклинг представление) объекты, хранящиеся в базе данных, должны быть довольно маленькими, и в редких случаях конфликты ключей могут привести к тому, что база данных откажется от обновлений.
  • Модуль shelve не поддерживает конкурентный доступ для чтения/записи к шелф объектам. (Множественные одновременные доступы для чтения безопасны.) Когда у программы есть шелф, открытый для записи, никакая другая программа не должна открывать его для чтения или записи. Для решения этой проблемы можно использовать блокировку файлов Unix, но она отличается в разных версиях Unix и требует знаний об используемой реализации базы данных.

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

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

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

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

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

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

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

Подкласс 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 - файл может получить суффикс, добавленный низкоуровневой # библиотекой d[key] = data # хранить данные по ключу (перезаписывает старые данные, если # используя существующий ключ) data = d[key] # получить КОПИЮ данных по ключу (вызывает KeyError # если нет такого ключа) del d[key] # удалить данные, хранящиеся в ключе (вызывает KeyError # если нет такого ключа) flag = key in d # true, если ключ существует klist = list(d.keys()) # список всех существующих ключей (медленно!) # поскольку d был открыт БЕЗ writeback=True, будьте осторожны: d['xx'] = [0, 1, 2] # это работает как положено, но . d['xx'].append(3) # *это не так!* -- d['xx'] все ещё [0, 1, 2]! # открыв d без writeback=True, вам нужно тщательно программировать: temp = d['xx'] # извлекает копию temp.append(5) # изменяет копию d['xx'] = temp # сохраняет копию обратно, чтобы сохранить ее # или d=shelve.open(filename,writeback=True) позволил бы вам простой код # d['xx'].append(5) и работать как положено, НО это также # потребляют больше памяти и замедляют работу d.close(). d.close() # закрыть его 

Модуль dbm Общий интерфейс к базам данных в стиле dbm . Модуль pickle Сериализация объекта, используемая shelve .

Источник

Shelve module in python

Для работы с бинарными файлами в Python может применяться еще один модуль — shelve . Он сохраняет объекты в файл с определенным ключом. Затем по этому ключу может извлечь ранее сохраненный объект из файла. Процесс работы с данными через модуль shelve напоминает работу со словарями, которые также используют ключи для сохранения и извлечения объектов.

Для открытия файла модуль shelve использует функцию open() :

open(путь_к_файлу[, flag="c"[, protocol=None[, writeback=False]]])

Где параметр flag может принимать значения:

  • c : файл открывается для чтения и записи (значение по умолчанию). Если файл не существует, то он создается.
  • r : файл открывается только для чтения.
  • w : файл открывается для записи.
  • n : файл открывается для записи Если файл не существует, то он создается. Если он существует, то он перезаписывается

Для закрытия подключения к файлу вызывается метод close() :

import shelve d = shelve.open(filename) d.close()

Либо можно открывать файл с помощью оператора with . Сохраним и считаем в файл несколько объектов:

import shelve FILENAME = "states2" with shelve.open(FILENAME) as states: states["London"] = "Great Britain" states["Paris"] = "France" states["Berlin"] = "Germany" states["Madrid"] = "Spain" with shelve.open(FILENAME) as states: print(states["London"]) print(states["Madrid"])

Запись данных предполагает установку значения для определенного ключа:

states["London"] = "Great Britain"

А чтение из файла эквивалентно получению значения по ключу:

В качестве ключей используются строковые значения.

При чтении данных, если запрашиваемый ключ отсутствует, то генерируется исключение. В этом случае перед получением мы можем проверять на наличие ключа с помощью оператора in :

with shelve.open(FILENAME) as states: key = "Brussels" if key in states: print(statesShelve module in python)

Также мы можем использовать метод get() . Первый параметр метода — ключ, по которому следует получить значение, а второй — значение по умолчанию, которое возвращается, если ключ не найден.

with shelve.open(FILENAME) as states: state = states.get("Brussels", "Undefined") print(state)

Используя цикл for, можно перебрать все значения из файла:

with shelve.open(FILENAME) as states: for key in states: print(key," - ", statesShelve module in python)

Метод keys() возвращает все ключи из файла, а метод values() — все значения:

with shelve.open(FILENAME) as states: for city in states.keys(): print(city, end=" ") # London Paris Berlin Madrid print() for country in states.values(): print(country, end=" ") # Great Britain France Germany Spain

Еще один метод items() возвращает набор кортежей. Каждый кортеж содержит ключ и значение.

with shelve.open(FILENAME) as states: for state in states.items(): print(state)
("London", "Great Britain") ("Paris", "France") ("Berlin", "Germany") ("Madrid", "Spain")

Обновление данных

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

import shelve FILENAME = "states2" with shelve.open(FILENAME) as states: states["London"] = "Great Britain" states["Paris"] = "France" states["Berlin"] = "Germany" states["Madrid"] = "Spain" with shelve.open(FILENAME) as states: states["London"] = "United Kingdom" states["Brussels"] = "Belgium" for key in states: print(key, " - ", statesShelve module in python)

Удаление данных

Для удаления с одновременным получением можно использовать функцию pop() , в которую передается ключ элемента и значение по умолчанию, если ключ не найден:

with shelve.open(FILENAME) as states: state = states.pop("London", "NotFound") print(state)

Также для удаления может применяться оператор del :

with shelve.open(FILENAME) as states: del states["Madrid"] # удаляем объект с ключом Madrid

Для удаления всех элементов можно использовать метод clear() :

with shelve.open(FILENAME) as states: states.clear()

Источник

Оцените статью