Почему назначение моим глобальным переменным не работает в 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 53

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) следующим образом:

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,в область, которую вы хотите использовать глобальную переменную. В данном случае, что в сета функция(значение). Так что скрипт становится:

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 рассматривается как локальная переменная, вам нужно определить

global a

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

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