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
См. также
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.7/library/shelve.html