2016-11-30 2 views
0

Я решил создать небольшой список отслеживания для личных нужд. Я создал два основных класса для хранения и обработки данных. Первый представляет собой предмет и список упражнений. Второе представляет каждое упражнение из списка упражнений (в основном только две переменные, все (целые) ответы и правильные (хорошие) ответы).Стеллаж (или рассол) не сохраняет правильную форму объектов. Он просто теряет данные

class Subject: 
    def __init__(self, name): 
     self.name = name 
     self.exercises = [] 

    def add(self, exc): 
     self.exercises.append(exc) 

    # here is also "estimate" and __str__ methods, but they don't matter 


class Exercise: 
    def __init__(self, good=0, whole=20): 
     self._good = good 
     self._whole = whole 

    def modify(self, good, whole=20): 
     self._good = good 
     self._whole = whole 

    # here is also "estimate" and __str__ methods, but they don't matter 

Я определил словарь, заполнил его экземплярами объекта, перевел его в файл полки и сохранил.

with shelve.open("shelve_classes") as db: 
    db.update(initiate()) 

Вот представление (инициируют состояние):

#Comma splices & Fused sentences (0.0%) 
#0/20  0.0% 
#0/20  0.0% 
#0/20  0.0% 
#0/20  0.0% 
#0/20  0.0% 

После этого я попытался возобновить сбрасывали файл и обновить некоторые значения.

with shelve.open('shelve_classes') as db: 
    key = 'Comma splices & Fused sentences' 
    sub = db[key] 
    sub.exercises[0].modify(18) 
    db[key] = sub 

Выглядит хорошо, давайте рассмотрим его:

print(db[key]) 

#Comma splices & Fused sentences (18.0%) 
#18/20  90.0% 
#0/20  0.0% 
#0/20  0.0% 
#0/20  0.0% 
#0/20  0.0% 

Но когда я закрываю файл, в следующий раз я открываю его, он возвращается, чтобы инициировать государственные и все исправления потерь. Даже попробовал его с рассолом, там тоже не работает. Не могу понять, почему он не сохраняет данные.

ответ

3

Модуль shelve не замечает, когда вы мутировать объект, только когда вы назначаете его:

Из-за семантики Python, полка не может знать, когда изменяемые настойчивый-запись словаря изменяется. По умолчанию модифицированные объекты записываются только при назначении полки.

Поэтому он не признает, что sub.exercises[0].modify(18) - это действие, которое необходимо переписать на диск.

Попробуйте установить флаг «writeback» на «Истина» при открытии дБ. Затем он снова сохранит db, когда он закроется, даже если он явно не обнаружил никаких изменений.

with shelve.open('shelve_classes', writeback=True) as db: 
    key = 'Comma splices & Fused sentences' 
    sub = db[key] 
    sub.exercises[0].modify(18) 
    db[key] = sub 
+0

Да, это работает, спасибо. На самом деле я нашел еще одну проблему с моим кодом. Все эти действия я сделал в отдельных файлах, и когда я попробовал его с помощью 'pickle', interprer попросил меня импортировать определенные классы в рабочий файл. Я сделал это, но потом решил переписать все с помощью 'shelve' и забыл удалить код импорта. И это как-то повлияло на выход. Все изменения сохраняются в файле, но когда я пытаюсь перезапустить скрипт, вывод каким-то образом заменяет исходные данные (с «полки») импортированными классами и показывает состояние начала. Не знаю, что это значит. В любом случае, спасибо. – tidylobster

-1

Вам не нужно закрывать db? Как

db.close() 
+0

В этом заключается красота инструкции 'with': она автоматически закрывает ресурс для вас, без необходимости делать что-либо. – Kevin

+0

Пока я писал свой комментарий, вы отправили свой. –

Смежные вопросы