Хотя модуль shelve достаточно сообразителен, чтобы обнаруживать множественные случаи вложенного объекта и воссоздавать только один экземпляр при загрузке, это относится только к данной ситуации:
dbase[key] = [object, object] # ОК: сохраняется и извлекается # только одна копия
dbase[key1] = object
dbase[key2] = object # плохо?: две копии объекта в хранилище
После извлечения объектов по ключам key1 и key2 они будут указывать на независимые копии оригинального общего объекта — если этот объект относится к категории изменяемых, изменения в одном из них не будут отражены в другом. В действительности это обусловлено тем, что каждое присвоение ключу запускает независимую операцию сериализации — механизм сериализации обнаруживает повторяющиеся объекты, но только в рамках одного обращения к модулю pickle. Это может не коснуться вас на практике и преодолевается введением дополнительной логики, но следует помнить, что объект может дублироваться, если он соответствует нескольким ключам.
Обновления должны выполняться в режиме «загрузить-модифицировать-сохранить»
Так как объекты, загруженные из хранилища, не знают, что они были извлечены оттуда, то операции, изменяющие части загруженного объекта, касаются только экземпляра, находящегося в памяти, а не данных в хранилище:
dbase[key].attr = value # данные в хранилище не изменились
Чтобы действительно изменить объект в хранилище, нужно загрузить его в память, изменить и записать обратно в хранилище целиком, выполнив присваивание по ключу:
object = dbase[key] # загрузить
object.attr = value # модифицировать
dbase[key] = object # записать обратно — хранилище изменилось
# (если при открытии не был указан аргумент writeback)
Как отмечалось выше, если методу shelve.open передать необязательный аргумент writeback, то выполнение последнего шага здесь не потребуется, — за счет автоматического кэширования извлеченных объектов и сохранения их на диске при закрытии хранилища. Но это может повлечь за собой существенный расход памяти и замедлить операцию закрытия.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011