Подтвердить что ты не робот

Глобальная переменная с импортом

first.py

myGlobal = "hello"

def changeGlobal():
   myGlobal="bye"

second.py

from first import *

changeGlobal()
print myGlobal

Выход, который я получаю,

Привет

хотя я думал, что это должно быть

до свидания

Почему глобальная переменная myGlobal не изменяется после вызова функции changeGlobal()?

Спасибо,

Joel

4b9b3361

Ответ 1

Try:

def changeGlobal():
    global myGlobal
    myGlobal = "bye"

Собственно, это тоже не работает. Когда вы import *, вы создаете новый local модуль global myGlobal, который невосприимчив к изменению, которое вы намереваетесь (если вы не изменяете переменную, см. Ниже). Вы можете использовать это вместо:

import nice

nice.changeGlobal()
print nice.myGlobal

Или:

myGlobal = "hello"

def changeGlobal():
   global myGlobal
   myGlobal="bye"

changeGlobal()

Однако, если ваш глобальный является изменяемым контейнером, теперь вы держите ссылку на изменяемый и можете видеть сделанные изменения:

myGlobal = ["hello"]

def changeGlobal():
    myGlobal[0] = "bye"

Ответ 2

У меня была такая же забота, как и у вас, и я прочитал следующий раздел от Norman Matloff Quick and Painless Python Tutorial действительно помог. Вот что вам нужно понять (скопировано из книги Матлоффа):

Python действительно не разрешает глобальные переменные в том смысле, что C/С++. Импортированный модуль Python не будет иметь прямого доступа к глобальным переменным в модуле, который импортирует его, и наоборот.

Например, рассмотрите эти два файла, x.py,

# x.py
import y
def f():
  global x
  x = 6
def main():
  global x
  x = 3
f()
y.g()
if __name__ == ’__main__’:
  main()

и y.py:

# y.py
def g():
  global x
  x += 1

Переменная x в x.py отображается во всем модуле x.py, но не в y.py. Фактически, выполнение линии x + = 1

в последнем случае появится сообщение об ошибке, "глобальное имя x не определено".

Действительно, глобальная переменная в модуле является всего лишь атрибутом (т.е. элементом-членом) этого модуля, аналогичным роли класса в классе. Когда модуль B импортируется модулем A, пространство имен B s копируется в A. Если модуль B имеет глобальную переменную X, тогда модуль A создаст переменную этого имени, начальным значением которой является любой модуль B для его переменной этого имени во время импорта. Но изменения X в одном из модулей НЕ будут отражены в другом.

Скажите, что X меняется в B, но мы хотим, чтобы код A мог получить последнее значение X в B. Мы можем сделать это, включив функцию, например, имя GetX() в B. Предполагая, что A импортирует все из B, тогда A получит функцию GetX(), которая является копией B s этого имени и единственной целью которого является вернуть значение X. Если B не изменит эту функцию (что возможно, например, функции могут быть назначены), функции в этих двух модулях будут всегда будет одинаковым, и поэтому A может использовать свою функцию для получения значения X в B.

Ответ 3

Глобальные переменные Python не являются глобальными

Как указано выше, они по существу являются атрибутами в рамках модуля, в котором они определены (или модуля, который содержит функцию, которая их определила).

Первые запутанные (ошибка) люди сталкиваются, не понимая, что функции имеют локальное пространство имен и что установка переменной в функции делает ее локальной для функции, даже когда они предназначены для нее, чтобы изменить (глобальную) переменную с тем же именем в прилагаемом модуле. (объявление имени в "глобальном" выражении в функции или при доступе к (глобальной) переменной перед ее настройкой.)

Вторая путаница (ошибка) сталкивается с тем, что каждый модуль (т.е. импортированный файл) содержит свое собственное так называемое глобальное пространство имен. Я думаю, что вещи python в мире (глобус) - это модуль - возможно, мы ищем "универсальные" переменные, которые охватывают более одного земного шара.

Третья путаница (которую я сейчас начинаю понимать) - где "глобальные" в модуле __main__? Т.е. если вы запускаете python из командной строки в интерактивном режиме или вы вызываете python script (введите имя foo.py из командной оболочки) - нет никакого импорта модуля, имя которого вы можете использовать.

Содержимое "globals()" или globals(). keys() - которое дает вам список глобалов - представляется доступным как: dir (sys.modules ['__main__']) Похоже, что модуль для загруженного python script (или интерактивный сеанс без загруженного script), тот, который указан в: __name__, не имеет глобального имени, но доступен как модуль с именем '__main__ 'в системном списке всех активных модулей, sys.modules