Почему полки не знают, когда было сделано изменение в изменчивом объекте? - PullRequest
1 голос
/ 10 апреля 2020

В настоящее время я прохожу онлайн-курс Udemy по программированию Python, и мы изучаем модуль shelve. Профессор показал, что по какой-то причине полка не может знать, когда изменяемый объект был изменен следующим образом: (он также объяснил способы обойти это)

import shelve

# Making a bunch of lists to bind to shelves later
blt = ["bacon", "tomato", "lettuce", "bread"]
beans_on_toast = ["beans", "bread"]
scrambled_eggs = ["eggs", "butter", "milk"]
soup = ["tin of soup"]
pasta = ["pasta", "cheese"]


with shelve.open('recipes') as recipes:
    # Binding each list to a shelve
    recipes['blt'] = blt
    recipes['beans on toast'] = beans_on_toast
    recipes['scrambled eggs'] = scrambled_eggs
    recipes['pasta'] = pasta
    recipes['soup'] = soup

    # Attempting to append 'butter' and 'tomato' to respective lists
    recipes['blt'].append("butter")
    recipes['pasta'].append("tomato")

    for snack in recipes:
        print(snack, recipes[snack])

Вывод из l oop показывает, что полки не изменились, и значения «масло» и «помидор» не были добавлены на соответствующие полки.

Мой онлайн-профессор пытался объяснить, почему это так, но я возникли проблемы с пониманием. Если бы кто-нибудь попытался объяснить это мне, я был бы признателен.

И если у вас хватит терпения, не могли бы вы объяснить какие-либо термины, которые вы могли бы использовать в своем ответе, которые, как вы думаете, я бы не понял. Я все еще начинающий, и Python - первый язык, который я изучаю. Заранее спасибо!

1 Ответ

0 голосов
/ 10 апреля 2020

Представьте, что ваша полка recipes представляет собой физическую книгу рецептов на вашей кухне.

recipes['blt'] = blt записывает в книгу рецепт приготовления ди sh, как blt.

* 1007. * При доступе к recipes['blt'] получается ди sh на основе рецепта.

recipes['blt'].append("butter") делает ди sh, а затем добавляет к нему масло. Рецепт в книге не включает в себя масло; если вы хотите переписать рецепт, вам придется сделать это отдельно.


Вот как работает shelve. Объект Shelf поддерживается файлом данных на диске, и каждая запись в файле содержит инструкции (в формате pickle ) для построения объекта. Доступ к полке создает объект на основе сохраненных инструкций, но изменение созданного вами объекта не изменит инструкции.

Если вы создаете полку с writeback=True, то вместо создания нового объекта на каждом При доступе к записи полка будет кэшировать встроенные объекты и снова возвращать тот же объект, если вы снова получите доступ к той же записи. Он по-прежнему не имеет ни малейшего представления, когда вы что-либо меняете, но, поскольку он возвращает тот же объект, изменения все еще присутствуют.

Когда вы закрываете полку writeback=True, полка будет писать новые огурцы для объектов, когда полка закрыта. Новые соленья будут отражать любые изменения объектов. Это может потребовать много ненужных записей, поскольку полка все еще не знает, когда вы изменили объект, поэтому она должна перебрать все из них, даже неизмененные.

...