【问题标题】:Why doesn't shelve know when a change has been made to a mutable object?为什么搁置不知道何时对可变对象进行了更改?
【发布时间】:2020-04-10 00:49:25
【问题描述】:

我目前正在参加有关 Python 编程的在线 Udemy 课程,我们正在学习搁置模块。教授已经表明,由于某种原因,搁置者无法知道可变对象何时发生了这样的变化:(他也解释了解决方法)

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])

for 循环的输出显示货架没有改变,并且值 'butter' 和 'tomato' 没有附加到它们各自的货架上。

我的在线教授试图解释为什么会这样,但我无法理解。如果有人可以尝试向我解释,我将不胜感激。

如果您有耐心,您能否解释一下您在回答中可能使用的任何您认为我不会理解的术语。我还是个初学者,Python 是我学习的第一门语言。提前致谢!

【问题讨论】:

  • 它怎么会知道?你有没有想到一个特定的机制?
  • 机制?我只是想知道为什么我对书架的更新没有反映在输出中。
  • 通过什么方式你希望书架知道你的更新吗?
  • 我认为 .append 方法可以做到。

标签: python module shelve


【解决方案1】:

将您的 recipes 架子想象成您厨房中的一本实体食谱。

recipes['blt'] = blt 在书中写了一个食谱,用于制作像blt 这样的菜。

访问recipes['blt'] 根据食谱制作一道菜。

recipes['blt'].append("butter") 做一道菜,然后往里面加黄油。书中的食谱并没有突然涉及黄油。如果您想重写配方,则必须单独进行。


这基本上就是shelve 的工作原理。 Shelf 对象由磁盘上的数据文件支持,文件中的每个条目都包含用于构建对象的指令(pickle 格式)。访问架子会根据存储的指令构建对象,但更改您构建的对象不会更改指令。

如果您使用writeback=True 创建架子,那么架子不会在每次访问条目时构建新对象,而是会缓存已构建的对象并在您再次访问同一条目时再次返回相同的对象。它仍然不知道您何时更改任何内容,但由于它返回相同的对象,因此更改仍然存在。

当您关闭 writeback=True 架子时,架子会在架子关闭时为对象写入新的泡菜。新的泡菜将反映对对象的任何更改。这可能涉及很多不必要的写入,因为架子实际上并不知道您何时更改了对象,因此它必须重新腌制所有对象,即使是未更改的对象。

【讨论】:

  • 我明白了这个逻辑,它解释了我的教授解释的解决方法之一,但是当我将 writeback 参数设置为 True 时会发生什么变化?因为在那个场合,它确实反映了更新。
  • @MaxwellN:答案已扩展。
  • 对不起,我刚刚重新加载了帖子,我看到了你的修改。谢谢!这很有帮助,你原来的答案现在更有意义了。谢谢你:)
猜你喜欢
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多