Почему назначение моих глобальных переменных не работает в Python?

у меня ужасные проблемы с попыткой понять правила определения области python.

со следующим скриптом:

a = 7

def printA():
    print "Value of a is %d" % (a)

def setA(value):
    a = value
    print "Inside setA, a is now %d" %(a)


print "Before setA"
printA()
setA(42)
print "After setA"
printA()

дает неожиданный (для меня) вывод:

    Before setA
    Value of a is 7
    Inside setA, a is now 42
    After setA
    Value of a is 7

где я ожидал бы, что последняя печать значения a будет 42, а не 7. Что мне не хватает в правилах области Python для области глобальных переменных?

5 ответов


глобальные переменные-это специальные. При попытке присвоить переменной a = value внутри функции он создает новую локальную переменную внутри функции, даже если есть глобальная переменная с тем же именем. Чтобы получить доступ к глобальной переменной, добавьте global сообщении внутри функции:

a = 7
def setA(value):
    global a   # declare a to be a global
    a = value  # this sets the global value of a

см. также именование и привязка для подробного объяснения правил именования и привязки Python.


трюк для понимания этого заключается в том, что когда вы назначаете переменной, используя=, вы также объявляете ее как локальную переменную. Таким образом, вместо изменения значения глобальной переменной a setA(value) фактически устанавливает локальную переменную (которая называется a) в переданное значение.

это становится более очевидным, если вы попытаетесь напечатать значение a в начале setA (value) следующим образом:

def setA(value):
    print "Before assignment, a is %d" % (a)
    a = value
    print "Inside setA, a is now %d" % (a)

Если вы попытаетесь запустить этот Python, это даст вам полезный ошибка:

Traceback (most recent call last):
  File "scopeTest.py", line 14, in 
    setA(42)
  File "scopeTest.py", line 7, in setA
    print "Before assignment, a is %d" % (a)
UnboundLocalError: local variable 'a' referenced before assignment

Это говорит нам, что Python решил, что функция setA(value) имеет локальную переменную, называемую a, которую вы изменяете, когда назначаете ей в функции. Если вы не назначаете a в функции (как с printA ()), то Python использует глобальную переменную A.

чтобы отметить переменную как глобальную, вам нужно использовать ключевое слово global в Python,в область, которую вы хотите использовать глобальную переменную. В данном случае, что в функция setA (value). Таким образом, сценарий становится:

a = 7

def printA():
    print "Value of a is %d" % (a)

def setA(value):
    global a
    a = value
    print "Inside setA, a is now %d" %(a)


print "Before setA"
printA()
setA(42)
print "After setA"
printA()

это добавление одной строки сообщает Python, что при использовании переменной a в функции setA(value) вы говорите о глобальной переменной, а не о локальной переменной.


Python не имеет понятия переменных, как и другие языки. У вас есть объекты, которые находятся "где-то", и у вас есть ссылки на эти объекты. = используется для присвоения этих объектов ссылкам в настоящее пространство имен.

вы создаете имя a в пространстве имен функции setA, которая ссылается на объект, к которому относится значение.


внутри функции,a рассматривается как локальная переменная, вам нужно определить

глобальный a

внутри функции


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