Почему reset глобальное значение python не вступает в силу
Просто путайте о глобальном значении в Python, вот два фрагмента кода
#gl.py
import cli
a = 1
print "gl 1: %d %d" % (id(a), a)
def reset():
global a
a = 7
print "reset 1: %d %d" % (id(a), a)
if __name__ == '__main__':
cli.handler(reset)
print "gl 2: %d %d" % (id(a), a)
код cli
#cli.py
def handler(func):
from gl import a
print "cli 1: %d %d" % (id(a), a)
func()
print "cli 2: %d %d" % (id(a), a)
Результатом выполнения является
$ python gl.py
gl 1: 150847672 1
gl 1: 150847672 1
cli 1: 150847672 1
reset 1: 150847600 7
cli 2: 150847672 1 #Why value doesn't change
gl 2: 150847600 7
Здесь я не понимаю после выполнения функции reset(), результат глобального значения не изменяется в cli.py(cli 2: 150847672 1), но обратно to gl.py, глобальное значение действительно меняется!
Ответы
Ответ 1
Здесь отсутствуют две концепции.
- Глобалы являются глобальными для модулей, а не через модули.
Refer: http://legacy.python.org/doc/essays/ppt/hp-training/sld036.htm
Обратитесь: http://docs.python.org/release/2.4/ref/global.html
- Переменные импортируются как значения, а не по ссылке
Обратитесь: fooobar.com/questions/149589/...
Если вам нужно поделиться глобальными переменными через модули, обратитесь к Как мне поделиться глобальными переменными между модулями?
Ответ 2
Ваш модуль gl
дважды импортируется в два разных пространства имен
попробуйте следующее:
import sys
print sys.modules['__main__'].a
print sys.modules['gl'].a
Ответ 3
Влияние, которое вы импортируете в cli, на самом деле является копией объекта модуля.
если мы изменим ваш код следующим образом:
#gl.py
import cli
import sys
a = 1
print "gl 1: %d %d" % (id(a), a)
print "gl id on import: {0}".format(id(sys.modules[__name__]))
def reset():
global a
a = 7
print "gl id in reset: {0}".format(id(sys.modules[__name__]))
print "reset 1: %d %d" % (id(a), a)
def printa():
print "gl: %d %d" % (id(a), a)
if __name__ == '__main__':
cli.handler(reset)
print "gl id in main: {0}".format(id(sys.modules[__name__]))
print "gl 2: %d %d" % (id(a), a)
и
#cli.py
def handler(func):
#from gl import a
import gl
print "gl id in cli: {0}".format(id(gl))
print "cli 1: %d %d" % (id(gl.a), gl.a)
func()
print "cli 2: %d %d" % (id(gl.a), gl.a)
gl.reset()
print "cli 3: %d %d" % (id(gl.a), gl.a)
Получаем:
gl 1: 19056568 1
gl id on import: 140075849968728
gl 1: 19056568 1
gl id on import: 20004096
gl id in cli: 20004096
cli 1: 19056568 1
gl id in reset: 140075849968728
reset 1: 19056424 7
cli 2: 19056568 1
gl id in reset: 20004096
reset 1: 19056424 7
cli 3: 19056424 7
gl id in main: 140075849968728
gl 2: 19056424 7
Итак, когда мы запускаем reset, мы меняем ссылку
a -> 19056568
to
a -> 19056424
но только в одной копии gl. Другой (тот, который находится в cli) держится на старой ссылке.
Если мы запустим gl.reset() изнутри cli, ссылка на эту копию изменится, и мы получим ожидаемое изменение в cli.