Почему доступ к глобальным переменным работает через модуль импорта, а не из модуля импорта 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 бродить вокруг, бывшего нет.

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