Как изменить глобальные переменные?

Вот упрощенная версия проблемы обновления глобалов - в 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 находится в их соответствующих пространствах имен.

Другие вопросы по тегам