Reputation: 657
Suppose I have the following module:
blah.py
a = 1
someDict = {'a' : 1, 'b': 2, 'c' : 3}
In the next python session I get the following:
>>> 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
It appears that when I modify an object that I imported from another module, and then re-import that object, it recovers its original value expressed in the module. But this doesn't apply to values in a dictionary. If I want to recover the original value of someDict
after making any modification, I have to close the current python session and open a new one. I find that this is even true if I merely called a function that modifies the dict elements.
Why does this happen? And is there some way I can re-import the dictionary with its original value without starting a new python session?
Upvotes: 0
Views: 122
Reputation: 155403
Because you denamespaced the dict
(with from x import y
syntax), you need to do this as a two-step process (three including the necessary imports):
import importlib, blah
to gain access to the reload
function, and the actual module to call it onimportlib.reload(blah)
to throw away the module cache of blah
, and reread it afresh from disk (the fresh version is stored in the cache, so future import
s related to blah
see the new version)from blah import a, someDict
again to pull the refreshed contents of blah
The reason you didn't see a problem with a
is that after doing from blah import a
, a
wasn't special; __main__.a
was just another alias to blah.a
, but since a = 100
rebinds a
to a completely new int
anyway (and since int
s are immutable, even a += 100
would actually perform a rebinding), you never changed blah.a
(you'd have to explicitly do import blah
, blah.a = 100
to have that happen).
someDict
was a problem because, like a
, __main__.someDict
and blah.someDict
end up as aliases of the same dict
, and you mutate that dict
, you're not rebinding __main__.someDict
itself. If you want to avoid mutating blah
's values in the first place, make sure the first modification to someDict
rebinds it to a fresh dict
, rather than modifying the one it's sharing with blah
, e.g. instead of:
someDict['a'] = 100
do:
someDict = {**someDict, 'a': 100}
to make a fresh dict
with a copy of blah.someDict
, but with the value of 'a'
in it replaced with a new value.
Upvotes: 4