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

shelve.md

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

1> **Источник:** https://python-all.ru/3.4/library/shelve.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 12.3. [`shelve`](https://python-all.ru/3.4/library/shelve.html#module-shelve) – сохранение объектов Python89**Исходный код:** [Lib/shelve.py](https://python-all.ru/src/3.4/Lib/shelve.py)1011---1213«Полка» (shelf) – это постоянный объект, похожий на словарь. Отличие от баз данных «dbm» в том, что значения (не ключи!) в полке могут быть практически произвольными объектами Python – всем, что поддерживает модуль [`pickle`](https://python-all.ru/3.4/library/pickle.html#module-pickle). Сюда входят большинство экземпляров классов, рекурсивные типы данных и объекты, содержащие множество общих подобъектов. Ключи – обычные строки.1415#### `shelve.open(filename, flag='c', protocol=None, writeback=False)`1617Открывает постоянный словарь. Указанное имя файла является базовым именем для базового файла базы данных. Как побочный эффект, к имени файла может быть добавлено расширение и может быть создано более одного файла. По умолчанию базовый файл базы данных открывается для чтения и записи. Необязательный параметр *flag* имеет ту же интерпретацию, что и параметр *flag* в функции [`dbm.open()`](https://python-all.ru/3.4/library/dbm.html#dbm.open).1819По умолчанию для сериализации значений используются pickle версии 3. Версию протокола pickle можно указать с помощью параметра *протокол*.2021Из-за семантики Python полка не может узнать, когда изменяется изменяемая запись постоянного словаря. По умолчанию изменённые объекты записываются *только* при присваивании полке (см. [*Пример*](https://python-all.ru/3.4/library/shelve.html#shelve-example)). Если необязательный параметр *writeback* установлен в *True*, все accessed записи также кэшируются в памяти и записываются обратно при вызове [`sync()`](https://python-all.ru/3.4/library/shelve.html#shelve.Shelf.sync) и [`close()`](https://python-all.ru/3.4/library/shelve.html#shelve.Shelf.close); это может упростить изменение изменяемых записей в постоянном словаре, но, если получено много записей, может потреблять огромные объёмы памяти для кэша и сделать операцию закрытия очень медленной, так как все полученные записи записываются обратно (нет способа определить, какие из полученных записей являются изменяемыми, и какие из них были фактически изменены).2223> **Примечание**24>25> Не полагайтесь на автоматическое закрытие полки; всегда вызывайте [`close()`](https://python-all.ru/3.4/library/shelve.html#shelve.Shelf.close) явно, когда она больше не нужна, или используйте [`shelve.open()`](https://python-all.ru/3.4/library/shelve.html#shelve.open) в качестве менеджера контекста:26>27> ```python28> with shelve.open('spam') as db:29>     db['eggs'] = 'eggs'30> ```3132> **Предупреждение**33>34> Поскольку модуль [`shelve`](https://python-all.ru/3.4/library/shelve.html#module-shelve) основан на [`pickle`](https://python-all.ru/3.4/library/pickle.html#module-pickle), загружать полку из ненадёжного источника небезопасно. Как и в случае с pickle, загрузка полки может выполнить произвольный код.3536Объекты Shelf поддерживают все методы, поддерживаемые словарями. Это облегчает переход от скриптов, основанных на словарях, к скриптам, требующим постоянного хранения.3738Поддерживаются два дополнительных метода:3940#### `Shelf.sync()`4142Записывает обратно все записи в кэше, если полка была открыта с *writeback* установленным в [`True`](https://python-all.ru/3.4/library/constants.html#True). Также очищает кэш и синхронизирует постоянный словарь на диске, если это возможно. Это вызывается автоматически, когда полка закрывается с помощью [`close()`](https://python-all.ru/3.4/library/shelve.html#shelve.Shelf.close).4344#### `Shelf.close()`4546Синхронизирует и закрывает постоянный объект *dict*. Операции над закрытой полкой будут завершаться с [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError).4748> **См. также**49>50> [Рецепт постоянного словаря](https://python-all.ru/3.4/library/shelve.html) с широко поддерживаемыми форматами хранения и скоростью нативных словарей.5152## 12.3.1. Ограничения5354>5556- Выбор того, какой пакет базы данных будет использоваться (например, [`dbm.ndbm`](https://python-all.ru/3.4/library/dbm.html#module-dbm.ndbm) или [`dbm.gnu`](https://python-all.ru/3.4/library/dbm.html#module-dbm.gnu)), зависит от того, какой интерфейс доступен. Поэтому небезопасно открывать базу данных напрямую с помощью [`dbm`](https://python-all.ru/3.4/library/dbm.html#module-dbm). Кроме того, база данных, к сожалению, подвержена ограничениям [`dbm`](https://python-all.ru/3.4/library/dbm.html#module-dbm), если она используется – это означает, что (сериализованное (pickle) представление) объектов, хранящихся в базе данных, должно быть достаточно маленьким, и в редких случаях коллизии ключей могут привести к тому, что база данных откажется обновляться.57- Модуль [`shelve`](https://python-all.ru/3.4/library/shelve.html#module-shelve) не поддерживает *одновременный* доступ на чтение и запись к объектам полки. (Множественные одновременные чтения безопасны.) Когда программа открывает полку для записи, никакая другая программа не должна открывать её для чтения или записи. Для решения этой проблемы можно использовать файловые блокировки Unix, но это отличается в разных версиях Unix и требует знания используемой реализации базы данных.5859#### `class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8')`6061Подкласс [`collections.abc.MutableMapping`](https://python-all.ru/3.4/library/collections.abc.html#collections.abc.MutableMapping), который хранит сериализованные с помощью pickle значения в объекте *dict*.6263По умолчанию для сериализации значений используется версия 0 pickle. Версию протокола pickle можно указать через параметр *protocol*. См. документацию [`pickle`](https://python-all.ru/3.4/library/pickle.html#module-pickle) для обсуждения протоколов pickle.6465Если параметр *writeback* равен `True`, объект будет хранить кэш всех полученных записей и записывать их обратно в *dict* при синхронизации и закрытии. Это позволяет естественным образом работать с изменяемыми записями, но может потреблять гораздо больше памяти и замедлить синхронизацию и закрытие.6667Параметр *keyencoding* – это кодировка, используемая для кодирования ключей перед их использованием в нижележащем словаре.6869Объект [`Shelf`](https://python-all.ru/3.4/library/shelve.html#shelve.Shelf) также можно использовать как менеджер контекста, и в этом случае он будет автоматически закрыт по завершении блока [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with).7071Изменено в версии 3.2: Добавлен параметр *keyencoding*; ранее ключи всегда кодировались в UTF-8.7273Изменено в версии 3.4: Добавлена поддержка менеджера контекста.7475#### `class shelve.BsdDbShelf(dict, protocol=None, writeback=False, keyencoding='utf-8')`7677Подкласс [`Shelf`](https://python-all.ru/3.4/library/shelve.html#shelve.Shelf), который предоставляет методы `first()`, `next()`, `previous()`, `last()` и `set_location()`, которые доступны в стороннем модуле `bsddb` (из пакета [pybsddb](https://python-all.ru/3.4/library/shelve.html)), но отсутствуют в других модулях баз данных. Объект *dict*, передаваемый конструктору, должен поддерживать эти методы. Обычно это достигается вызовом одной из функций: `bsddb.hashopen()`, `bsddb.btopen()` или `bsddb.rnopen()`. Необязательные параметры *protocol*, *writeback* и *keyencoding* имеют ту же интерпретацию, что и для класса [`Shelf`](https://python-all.ru/3.4/library/shelve.html#shelve.Shelf).7879#### `class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False)`8081Подкласс [`Shelf`](https://python-all.ru/3.4/library/shelve.html#shelve.Shelf), который принимает имя файла *filename* вместо объекта, похожего на словарь. Базовый файл будет открыт с помощью [`dbm.open()`](https://python-all.ru/3.4/library/dbm.html#dbm.open). По умолчанию файл будет создан и открыт для чтения и записи. Необязательный параметр *flag* имеет ту же интерпретацию, что и для функции [`open()`](https://python-all.ru/3.4/library/shelve.html#shelve.open). Необязательные параметры *protocol* и *writeback* имеют ту же интерпретацию, что и для класса [`Shelf`](https://python-all.ru/3.4/library/shelve.html#shelve.Shelf).8283## 12.3.2. Пример8485Обобщая интерфейс (`key` – строка, `data` – произвольный объект):8687```python88import shelve8990d = shelve.open(filename) # open -- файл может получить суффикс, добавленный низкоуровневой91                          # библиотекой9293d[key] = data   # сохраняет данные по ключу (перезаписывает старые данные, если94                # используется существующий ключ)95data = d[key]   # извлечь копию данных по ключу (вызывает KeyError, если такого ключа нет)96                # такого ключа)97del d[key]      # удалить данные, хранящиеся по ключу (вызывает KeyError98                # если такого ключа нет)99flag = key in d        # true, если ключ существует100klist = list(d.keys()) # список всех существующих ключей (медленно!)101102# так как d был открыт БЕЗ writeback=True, внимание:103d['xx'] = [0, 1, 2]    # это работает как ожидается, но...104d['xx'].append(3)      # *это не работает!* -- d['xx'] всё ещё [0, 1, 2]!105106# открыв d без writeback=True, нужно писать код аккуратно:107temp = d['xx']      # извлекает копию108temp.append(5)      # изменяет копию109d['xx'] = temp      # сохраняет изменённую копию обратно для сохранения110111# или, d=shelve.open(filename,writeback=True) позволил бы просто написать112# d['xx'].append(5) и это бы работало как ожидается, НО это также бы113# потребляло больше памяти и замедляло операцию d.close().114115d.close()       # закрыть его116```117118> **См. также**119>120> **Модуль [`dbm`](https://python-all.ru/3.4/library/dbm.html#module-dbm)**121>122> Общий интерфейс для баз данных типа123>124> `dbm`125>126> .127>128> **Модуль [`pickle`](https://python-all.ru/3.4/library/pickle.html#module-pickle)**129>130> Сериализация объектов, используемая модулем131>132> [`shelve`](https://python-all.ru/3.4/library/shelve.html#module-shelve)133>134> .135