如何在不修改当前会话的情况下重新导入字典对象?

How to re-import a dictionary object without a modification made in the current session?

假设我有以下模块:

blah.py

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 会话并打开一个新会话。我发现即使我只是调用一个修改字典元素的函数也是如此。

为什么会这样?有没有什么方法可以在不启动新的 python 会话的情况下重新导入字典的原始值?

因为您取消了 dict 的命名空间(使用 from x import y 语法),您需要分两步执行此操作(三步包括必要的导入):

  1. 执行 import importlib, blah 以获得对 the reload function 的访问权限,以及调用它的实际模块
  2. 运行 importlib.reload(blah) 扔掉blah的模块缓存,从磁盘重新读取(新版本存入缓存,所以以后importblah 相关,请参阅新版本)
  3. 运行from blah import a, someDict再次拉取blah
  4. 的刷新内容

您没有发现 a 问题的原因是在执行 from blah import a 之后,a 并不特别; __main__.a 只是 blah.a 的另一个别名,但是由于 a = 100 重新绑定 a 到一个全新的 int (并且由于 int 是不可变的,即使 a += 100 实际上也会执行重新绑定),您从未更改过 blah.a(您必须明确地执行 import blahblah.a = 100 让那件事发生)。

someDict 是一个问题,因为像 a__main__.someDictblah.someDict 最终成为相同 dict 的别名,而你 mutate dict,你没有重新绑定 __main__.someDict 本身。如果您想首先避免改变 blah 的值,请确保对 someDict 的第一次修改将其重新绑定到新的 dict,而不是修改它与 [=共享的值=17=],例如而不是:

someDict['a'] = 100

做:

someDict = {**someDict, 'a': 100}

blah.someDict 的副本制作一个新的 dict,但其中 'a' 的值替换为新值。