Как изменить глобальные переменные?
Вот упрощенная версия проблемы обновления глобалов - в test.py
Я имею:
k1 = 1
def set_v(k, v):
if k in globals():
globals()[k] = v;
read_v()
def read_v():
print("after {}".format(k1))
Код запускается из интерпретатора Python после выполнения:
from test.py import *
дает...
>>> k1
1
>>> set_v('k1',2)
after 2
>>> set_v('k1',3)
after 3
>>> k1
1
Я не могу понять это.k1
имеет глобальный охват как read_v()
видит это в глобальном dict
, Почему глобальный k1
видимый для переводчика не изменяется? я пытался setattr(module, var, val)
... но это ничем не отличается от этого.
2 ответа
Глобальные в Python являются глобальными только внутри модуля.
Если вы хотите изменить глобал в импортированном модуле, вам нужно получить к нему доступ, используя module.variable
,
В контексте вашего теста это означает:
import test.py as test
from test.py import *
print(test.k1)
set_v('k1',2)
set_v('k1',3)
print(test.k1)
Выход:
1
after 2
after 3
3
Когда вы делаете from test import *
Вы вносите все эти объекты и функции в свое пространство имен. У вас есть ссылка на k1
в то время как test
также имеет ссылку на k1
, Но ссылки не совпадают. Они разные.
Попробуй это:
>>> import test
>>> from test import *
>>> set_v('k1', 3)
after 3
>>> k1
1
>>> test.k1
3
Изменить ваш set_v
Функция также распечатать идентификатор. Вы увидите, что test
"s k1
и k1
которые импортируются в ваш сеанс REPL разные.
Вывод: каждая версия k1
находится в их соответствующих пространствах имен.