Документация Python неофициальный перевод

shelve.md

142 строк · 15.5 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/2.7/library/shelve.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 11.4. [`shelve`](https://python-all.ru/2.7/library/shelve.html#module-shelve) – сохранение объектов Python89**Исходный код:** [Lib/shelve.py](https://python-all.ru/src/2.7/Lib/shelve.py)1011---1213«Полка» (shelf) – это постоянный объект, похожий на словарь. Отличие от баз данных «dbm» в том, что значения (не ключи!) на полке могут быть практически произвольными объектами Python – всем, с чем может работать модуль [`pickle`](https://python-all.ru/2.7/library/pickle.html#module-pickle). Сюда входят большинство экземпляров классов, рекурсивные типы данных и объекты, содержащие много общих подобъектов. Ключи – обычные строки.1415#### `shelve.open(filename, flag='c', protocol=None, writeback=False)`1617Открывает постоянный словарь. Указанное имя файла является базовым для нижележащей базы данных. Как побочный эффект, к имени файла может быть добавлено расширение, и может быть создано более одного файла. По умолчанию нижележащий файл базы данных открывается для чтения и записи. Необязательный параметр *flag* имеет ту же интерпретацию, что и параметр *flag* функции [`anydbm.open()`](https://python-all.ru/2.7/library/anydbm.html#anydbm.open).1819По умолчанию для сериализации значений используются pickle версии 0. Версию протокола pickle можно указать с помощью параметра *protocol*.2021Изменено в версии 2.3: Был добавлен параметр *протокол*.2223Из-за семантики Python полка не может узнать, когда изменяется изменяемая запись постоянного словаря. По умолчанию изменённые объекты записываются *только* при присваивании полке (см. [Пример](https://python-all.ru/2.7/library/shelve.html#shelve-example)). Если необязательный параметр *writeback* установлен в `True`, все запрашиваемые записи также кэшируются в памяти и записываются обратно при вызове [`sync()`](https://python-all.ru/2.7/library/shelve.html#shelve.Shelf.sync) и [`close()`](https://python-all.ru/2.7/library/shelve.html#shelve.Shelf.close); это может упростить изменение изменяемых записей в постоянном словаре, но, если запрашивается много записей, может потреблять огромные объёмы памяти для кэша, а также может сделать операцию закрытия очень медленной, так как все запрошенные записи записываются обратно (нет способа определить, какие из запрошенных записей являются изменяемыми и какие из них были фактически изменены).2425Как и файловые объекты, объекты shelve следует явно закрывать, чтобы гарантировать сброс персистентных данных на диск.2627> **Предупреждение**28>29> Поскольку модуль [`shelve`](https://python-all.ru/2.7/library/shelve.html#module-shelve) основан на [`pickle`](https://python-all.ru/2.7/library/pickle.html#module-pickle), загружать полку из ненадёжного источника небезопасно. Как и в случае с pickle, загрузка полки может выполнить произвольный код.3031Объекты Shelf поддерживают большинство методов, поддерживаемых словарями. Это упрощает переход от скриптов, основанных на словарях, к скриптам, требующим персистентного хранения.3233Примечание: методы перехода на Python 3 ([`viewkeys()`](https://python-all.ru/2.7/library/stdtypes.html#dict.viewkeys), [`viewvalues()`](https://python-all.ru/2.7/library/stdtypes.html#dict.viewvalues) и [`viewitems()`](https://python-all.ru/2.7/library/stdtypes.html#dict.viewitems)) не поддерживаются.3435Поддерживаются два дополнительных метода:3637#### `Shelf.sync()`3839Записывает обратно все записи из кэша, если полка была открыта с *writeback*, установленным в [`True`](https://python-all.ru/2.7/library/constants.html#True). Также очищает кэш и синхронизирует постоянный словарь на диске, если это возможно. Вызывается автоматически при закрытии полки с помощью [`close()`](https://python-all.ru/2.7/library/shelve.html#shelve.Shelf.close).4041#### `Shelf.close()`4243Синхронизирует и закрывает постоянный объект *dict*. Операции над закрытой полкой завершатся ошибкой [`ValueError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.ValueError).4445> **См. также**46>47> [Рецепт постоянного словаря](https://python-all.ru/2.7/library/shelve.html) с широко поддерживаемыми форматами хранения и скоростью нативных словарей.4849## 11.4.1. Ограничения5051>5253- Выбор используемого пакета базы данных (например, [`dbm`](https://python-all.ru/2.7/library/dbm.html#module-dbm), [`gdbm`](https://python-all.ru/2.7/library/gdbm.html#module-gdbm) или [`bsddb`](https://python-all.ru/2.7/library/bsddb.html#module-bsddb)) зависит от того, какой интерфейс доступен. Поэтому небезопасно открывать базу данных напрямую с помощью [`dbm`](https://python-all.ru/2.7/library/dbm.html#module-dbm). База данных также (к сожалению) подвержена ограничениям [`dbm`](https://python-all.ru/2.7/library/dbm.html#module-dbm), если он используется – это означает, что представление объектов, хранящихся в базе данных, в pickle должно быть достаточно маленьким, и в редких случаях коллизии ключей могут привести к отказу базы данных в обновлениях.54- Модуль [`shelve`](https://python-all.ru/2.7/library/shelve.html#module-shelve) не поддерживает *одновременный* доступ на чтение и запись к объектам на полке. (Одновременный доступ на чтение от нескольких программ безопасен.) Когда программа открыла полку для записи, никакая другая программа не должна открывать её для чтения или записи. Для решения этой проблемы можно использовать блокировку файлов в Unix, но она отличается в разных версиях Unix и требует знания используемой реализации базы данных.5556#### `class shelve.Shelf(dict, protocol=None, writeback=False)`5758Подкласс [`UserDict.DictMixin`](https://python-all.ru/2.7/library/userdict.html#UserDict.DictMixin), который хранит значения, сериализованные в pickle, в объекте *dict*.5960По умолчанию для сериализации значений используются pickle версии 0. Версию протокола pickle можно указать с помощью параметра *protocol*. См. документацию [`pickle`](https://python-all.ru/2.7/library/pickle.html#module-pickle) для обсуждения протоколов pickle.6162Изменено в версии 2.3: Был добавлен параметр *протокол*.6364Если параметр *writeback* равен `True`, объект будет хранить кэш всех запрошенных записей и записывать их обратно в *dict* при синхронизации и закрытии. Это позволяет естественно работать с изменяемыми записями, но может потреблять значительно больше памяти и замедлять синхронизацию и закрытие.6566#### `class shelve.BsdDbShelf(dict, protocol=None, writeback=False)`6768Подкласс [`Shelf`](https://python-all.ru/2.7/library/shelve.html#shelve.Shelf), который предоставляет `first()`, `next()`, `previous()`, `last()` и `set_location()`, доступные в модуле [`bsddb`](https://python-all.ru/2.7/library/bsddb.html#module-bsddb), но отсутствующие в других модулях баз данных. Объект *dict*, передаваемый конструктору, должен поддерживать эти методы. Обычно это достигается вызовом одной из функций [`bsddb.hashopen()`](https://python-all.ru/2.7/library/bsddb.html#bsddb.hashopen), [`bsddb.btopen()`](https://python-all.ru/2.7/library/bsddb.html#bsddb.btopen) или [`bsddb.rnopen()`](https://python-all.ru/2.7/library/bsddb.html#bsddb.rnopen). Необязательные параметры *protocol* и *writeback* имеют ту же интерпретацию, что и для класса [`Shelf`](https://python-all.ru/2.7/library/shelve.html#shelve.Shelf).6970#### `class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False)`7172Подкласс [`Shelf`](https://python-all.ru/2.7/library/shelve.html#shelve.Shelf), который принимает *filename* вместо объекта, похожего на словарь. Базовый файл будет открыт с помощью [`anydbm.open()`](https://python-all.ru/2.7/library/anydbm.html#anydbm.open). По умолчанию файл создаётся и открывается для чтения и записи. Необязательный параметр *flag* имеет то же значение, что и для функции [`open()`](https://python-all.ru/2.7/library/shelve.html#shelve.open). Необязательные параметры *протокол* и *writeback* имеют то же значение, что и для класса [`Shelf`](https://python-all.ru/2.7/library/shelve.html#shelve.Shelf).7374## 11.4.2. Пример7576Обобщая интерфейс (`key` – строка, `data` – произвольный объект):7778```python79import shelve8081d = shelve.open(filename) # open -- файл может получить суффикс, добавленный низкоуровневой82                          # библиотекой8384d[key] = data   # сохраняет данные по ключу (перезаписывает старые данные, если85                # используется существующий ключ)86data = d[key]   # извлечь копию данных по ключу (вызывает KeyError, если такого ключа нет)87                # такого ключа)88del d[key]      # удалить данные, хранящиеся по ключу (вызывает KeyError89                # если такого ключа нет)90flag = d.has_key(key)   # true, если ключ существует91klist = d.keys() # список всех существующих ключей (медленно!)9293# так как d был открыт БЕЗ writeback=True, внимание:94d['xx'] = range(4)  # это работает как ожидается, но...95d['xx'].append(5)   # *это не так!* -- d['xx'] по-прежнему range(4)!9697# открыв d без writeback=True, нужно писать код аккуратно:98temp = d['xx']      # извлекает копию99temp.append(5)      # изменяет копию100d['xx'] = temp      # сохраняет изменённую копию обратно для сохранения101102# или, d=shelve.open(filename,writeback=True) позволил бы просто написать103# d['xx'].append(5) и это бы работало как ожидается, НО это также бы104# потребляло больше памяти и замедляло операцию d.close().105106d.close()       # закрыть его107```108109> **См. также**110>111> **Модуль [`anydbm`](https://python-all.ru/2.7/library/anydbm.html#module-anydbm)**112>113> Общий интерфейс для баз данных стиля `dbm`.114>115> **Модуль [`bsddb`](https://python-all.ru/2.7/library/bsddb.html#module-bsddb)**116>117> Интерфейс базы данных `db` BSD.118>119> **Модуль [`dbhash`](https://python-all.ru/2.7/library/dbhash.html#module-dbhash)**120>121> Тонкая обёртка вокруг [`bsddb`](https://python-all.ru/2.7/library/bsddb.html#module-bsddb), которая предоставляет функцию [`open()`](https://python-all.ru/2.7/library/dbhash.html#dbhash.open), подобно другим модулям баз данных.122>123> **Модуль [`dbm`](https://python-all.ru/2.7/library/dbm.html#module-dbm)**124>125> Стандартный интерфейс базы данных Unix.126>127> **Модуль [`dumbdbm`](https://python-all.ru/2.7/library/dumbdbm.html#module-dumbdbm)**128>129> Переносимая реализация интерфейса `dbm`.130>131> **Модуль [`gdbm`](https://python-all.ru/2.7/library/gdbm.html#module-gdbm)**132>133> Интерфейс базы данных GNU, основанный на интерфейсе `dbm`.134>135> **Модуль [`pickle`](https://python-all.ru/2.7/library/pickle.html#module-pickle)**136>137> Сериализация объектов, используемая [`shelve`](https://python-all.ru/2.7/library/shelve.html#module-shelve).138>139> **Модуль [`cPickle`](https://python-all.ru/2.7/library/pickle.html#module-cPickle)**140>141> Высокопроизводительная версия [`pickle`](https://python-all.ru/2.7/library/pickle.html#module-pickle).142