Почему доступ к глобальным переменным работает через модуль импорта, а не из модуля импорта var?
Я много читал и изучал Python, но все варианты импорта, имеющие разные результаты, немного запутывают.
У меня возникла проблема, когда глобальная переменная, которую я импортировал, всегда была значением по умолчанию, хотя я и вызвал метод в этом модуле, который манипулирует им. Я импортировал это так:
from fona import connect, disconnect, CON
Где первые две функции, а последние - вар. Первые два открывают или закрывают соединение, к которому у меня есть доступ через var CON. Когда я делал это таким образом, CON оставался None, хотя connect успешно его инициализировал (у меня много подробных выводов, чтобы убедиться в этом). Я возился все больше и больше и не мог понять это. Написал пост, сильно отличающийся от этого, прежде чем у меня появилась еще одна идея.
import fona
Затем я получаю доступ ко всему через fona.connect/disco/CON. Тогда это работает. Я изо всех сил пытаюсь понять, почему и не мог найти никаких ресурсов. Чем отличается этот импорт? Мне очень нравится from x import y as z
, но, кажется, я не могу использовать это в этом случае.
2 ответа
В Python "глобальный" означает "уровень модуля" (на самом деле во время выполнения "глобальная" переменная является атрибутом module
экземпляр объекта).
Теперь это утверждение:
from fona import CON
является синтаксическим сахаром для:
import fona
CON = fona.CON
del fona
поэтому на данный момент у нас есть два имени, указывающие на один и тот же объект - fon.CON
а также <yourothermodule>.CON
Теперь, если в fona
у нас есть функция, которая связывает fona.CON
т.е.
def foo():
global CON
con = "XXX"
вызов этой функции ТОЛЬКО перепривязывает fona.CON
, не CON
переменная в <yourothermodule>
,
Если вместо этого вы импортируете весь fona
модуль и использование fona.CON
вы видите эффект переторжки после звонка fona.foo()
потому что вы на самом деле доступ к fona
атрибут модуля, а не ваш локальный (локальный) атрибут.
На самом деле у вас была бы та же самая ситуация с двумя диктовками в одном модуле:
d1 = {"a":1}
d2 = {}
d2["a"] = d1["a"]
d1["a"] = 42 # this won't change d2["a"]
print d1, d2
На самом деле вам даже не нужны диктовки, достаточно двух имен в одном и том же пространстве имен:
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
>>> a = 1
>>> b = a
>>> print a
1
>>> print b
1
>>> b is a
True
Как вы можете видеть, на данный момент b
не является "копией" a
На самом деле это просто другое имя, связанное с тем же объектом. Теперь, если мы перепривязать a
:
>>> a = 2
>>> print a
2
>>> print b
1
>>> b is a
False
>>>
мы видим, что это не влияет b
это только делает a
указать на другой объект.
from fona import CON
почти так же, как:
import fona
CON = fona.CON
Сейчас если fona
изменяется внутри так, чтобы fona.CON
заменяется новым значением, это не влияет на вашу собственную переменную. Также как если бы вы сказали:
y = 1
x = y
y = 2
x
все еще 1, хотя y
сейчас 2.
* кроме последнего оставляет имя fona
бродить вокруг, бывшего нет.