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



假设我有以下模块:

等等

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语法)的命名空间,所以需要将其分为两步(三步包括必要的导入):

  1. 执行import importlib, blah以访问reload函数,以及调用它的实际模块
  2. 运行importlib.reload(blah)丢弃blah的模块缓存,并从磁盘上重新读取(新版本存储在缓存中,因此与blah相关的未来import请参阅新版本)
  3. 再次运行from blah import a, someDict,拉取blah的刷新内容

你没有发现a有问题的原因是在做了from blah import a之后,a没有什么特别之处;__main__.a只是blah.a的另一个别名,但由于a = 100无论如何都会将a重新绑定到一个全新的int(而且由于ints是不可变的,即使是a += 100也会执行重新绑定),因此您从未更改blah.a(您必须显式地执行import blahblah.a = 100才能实现这一点)。

someDict是一个问题,因为与a__main__.someDictblah.someDict一样,它们最终成为同一dict的别名,并且您dict进行了变异,因此不会重新绑定__main__.someDict本身。如果您想从一开始就避免更改blah的值,请确保对someDict的第一次修改将其重新绑定到新的dict,而不是修改它与blah共享的值,例如,而不是:

someDict['a'] = 100

do:

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

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

最新更新