Как повторно импортировать объект словаря без изменений, сделанных в текущем сеансе? - PullRequest
0 голосов
/ 11 января 2019

Предположим, у меня есть следующий модуль:

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 и открыть новый. Я считаю, что это даже верно, если бы я просто вызвал функцию, которая изменяет элементы dict.

Почему это происходит? И есть ли способ, как я могу повторно импортировать словарь с его исходным значением, не начиная новый сеанс Python?

1 Ответ

0 голосов
/ 11 января 2019

Поскольку вы удалили пространство dict (с синтаксисом from x import y), вы должны сделать это как двухэтапный процесс (три, включая необходимый импорт):

  1. Выполните import importlib, blah, чтобы получить доступ к функции reload , и к фактическому модулю, который вызовет ее на
  2. Запустите importlib.reload(blah), чтобы выбросить кэш модуля blah и перечитать его заново с диска (свежая версия хранится в кэше, поэтому будущие import, связанные с blah, будут видеть новую версию)
  3. Запустите 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

сделать:

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

для создания нового dict с копией blah.someDict, но со значением 'a' в нем, замененным новым значением.

...