shelve — Постоянное хранение объектов Python
Исходный код: Lib/shelve.py
«Шелф» — это устойчивый объект, подобный словарю. Разница с базами данных «dbm» состоит в том, что значения (а не ключи!) в шельфе могут быть произвольными объектами Python — всё, что может обработать модуль pickle. Это включает большинство экземпляров классов, рекурсивные типы данных и объекты, содержащие много общих подобъектов. Ключи — обычные строки.
-
shelve.open(filename, flag='c', protocol=None, writeback=False) -
Открывает устойчивый словарь. Указанное имя файла является базовым именем для подлежащей базы данных. В качестве побочного эффекта к имени файла может быть добавлено расширение, и может быть создано более одного файла. По умолчанию, подлежащий файл базы данных открывается для чтения и записи. Необязательный параметр flag имеет такое же значение, как параметр flag функции
dbm.open().По умолчанию используются сериализованные значения версии 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.
См. также
Рецепт устойчивого словаря с широко поддерживаемыми форматами хранения и скоростью, аналогичной скорости встроенных словарей.
1. Ограничения
- Выбор пакета базы данных (например,
dbm.ndbmилиdbm.gnu) зависит от доступного интерфейса. Поэтому небезопасно открывать базу данных напрямую с помощьюdbm. База данных также (к сожалению) ограничена ограничениямиdbm, если она используется — это означает, что (сериализованное представление) хранящихся в базе данных объектов должно быть довольно маленьким, и в редких случаях коллизии ключей могут привести к отказу базы данных от обновлений. - Модуль
shelveне поддерживает одновременный доступ для чтения/записи к объектам шельфа. (Несколько одновременных обращений для чтения безопасны.) Когда программа открывает шельф для записи, никакая другая программа не должна открывать его для чтения или записи. Блокировка файлов Unix может быть использована для решения этой проблемы, но это отличается в различных версиях Unix и требует знаний о реализации используемой базы данных.
-
class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8') -
Подкласс
collections.abc.MutableMapping, который хранит сериализованные значения в объекте dict.По умолчанию используются сериализованные значения версии 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, который принимает filename вместо объекта dict. Подлежащий файл будет открыт с помощьюdbm.open(). По умолчанию файл будет создан и открыт для чтения и записи. Необязательный параметр flag имеет такое же значение, как для функцииopen(). Необязательные параметры protocol и writeback имеют такое же значение, как для классаShelf.
2. Пример
Для суммирования интерфейса (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.5/library/shelve.html