为什么搁置不知道何时对可变对象进行了更改?
Why doesn't shelve know when a change has been made to a mutable object?
我目前正在学习 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 是我学习的第一门语言。提前致谢!
将您的 recipes
架子想象成厨房中的物理食谱书。
recipes['blt'] = blt
在书上写了一个食谱,可以做一道像blt
这样的菜。
访问recipes['blt']
根据食谱制作菜肴。
recipes['blt'].append("butter")
做一道菜,然后加入黄油。书中的食谱并没有突然涉及黄油;如果您想重写食谱,则必须单独进行。
这基本上就是 shelve
的工作原理。 Shelf
对象由磁盘上的数据文件支持,文件中的每个条目都包含用于构建对象的说明(采用 pickle 格式)。访问货架会根据存储的指令构建一个对象,但更改您构建的对象不会更改指令。
如果您使用 writeback=True
创建 shelf,则不会在每次访问条目时构建新对象,shelf 将缓存构建的对象和 return 相同的对象,如果您再次访问相同的条目。它仍然不知道您何时更改任何内容,但由于它是 return 同一个对象,因此更改仍然存在。
当您关闭 writeback=True
架子时,架子将在架子关闭时为对象写入新的泡菜。新泡菜将反映对对象的任何更改。这可能涉及很多不必要的编写,因为 shelf 实际上仍然不知道您何时更改了对象,因此它必须重新 pickle 所有对象,即使是未更改的对象。
我目前正在学习 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 是我学习的第一门语言。提前致谢!
将您的 recipes
架子想象成厨房中的物理食谱书。
recipes['blt'] = blt
在书上写了一个食谱,可以做一道像blt
这样的菜。
访问recipes['blt']
根据食谱制作菜肴。
recipes['blt'].append("butter")
做一道菜,然后加入黄油。书中的食谱并没有突然涉及黄油;如果您想重写食谱,则必须单独进行。
这基本上就是 shelve
的工作原理。 Shelf
对象由磁盘上的数据文件支持,文件中的每个条目都包含用于构建对象的说明(采用 pickle 格式)。访问货架会根据存储的指令构建一个对象,但更改您构建的对象不会更改指令。
如果您使用 writeback=True
创建 shelf,则不会在每次访问条目时构建新对象,shelf 将缓存构建的对象和 return 相同的对象,如果您再次访问相同的条目。它仍然不知道您何时更改任何内容,但由于它是 return 同一个对象,因此更改仍然存在。
当您关闭 writeback=True
架子时,架子将在架子关闭时为对象写入新的泡菜。新泡菜将反映对对象的任何更改。这可能涉及很多不必要的编写,因为 shelf 实际上仍然不知道您何时更改了对象,因此它必须重新 pickle 所有对象,即使是未更改的对象。