假设我有以下模块:
等等
a = 1
someDict = {'a' : 1, 'b': 2, 'c' : 3}
在下一个python会话中,我得到以下内容:
>>> from blah import a, someDict
>>> a
1
>>> someDict
{'a': 1, 'b': 2, 'c': 3}
>>> a = 100
>>> someDict['a'] = 100
>>> del a, someDict
>>> from blah import a, someDict
>>> a
1
>>> someDict['a']
100
>>> import blah
>>> blah.someDict['a']
100
看起来,当我修改从另一个模块导入的对象,然后重新导入该对象时,它会恢复在模块中表示的原始值。但这并不适用于字典中的值。如果我想在进行任何修改后恢复someDict
的原始值,我必须关闭当前python会话并打开一个新会话。我发现,如果我只调用了一个修改dict元素的函数,这甚至是真的。
为什么会发生这种情况?有没有什么方法可以在不启动新的python会话的情况下重新导入具有原始值的字典?
因为您取消了dict
(使用from x import y
语法)的命名空间,所以需要将其分为两步(三步包括必要的导入):
- 执行
import importlib, blah
以访问reload
函数,以及调用它的实际模块 - 运行
importlib.reload(blah)
丢弃blah
的模块缓存,并从磁盘上重新读取(新版本存储在缓存中,因此与blah
相关的未来import
请参阅新版本) - 再次运行
from blah import a, someDict
,拉取blah
的刷新内容
你没有发现a
有问题的原因是在做了from blah import a
之后,a
没有什么特别之处;__main__.a
只是blah.a
的另一个别名,但由于a = 100
无论如何都会将a
重新绑定到一个全新的int
(而且由于int
s是不可变的,即使是a += 100
也会执行重新绑定),因此您从未更改blah.a
(您必须显式地执行import blah
、blah.a = 100
才能实现这一点)。
someDict
是一个问题,因为与a
、__main__.someDict
和blah.someDict
一样,它们最终成为同一dict
的别名,并且您对dict
进行了变异,因此不会重新绑定__main__.someDict
本身。如果您想从一开始就避免更改blah
的值,请确保对someDict
的第一次修改将其重新绑定到新的dict
,而不是修改它与blah
共享的值,例如,而不是:
someDict['a'] = 100
do:
someDict = {**someDict, 'a': 100}
用blah.someDict
的副本制作新的dict
,但其中的'a'
的值被新值替换。