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

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

У меня ужасная проблема, пытаясь понять правила обзора python.

Со следующим script:

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 для определения глобальных переменных?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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). Таким образом, script становится:

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) вы говорите о глобальной переменной, а не о локальной переменной.

Ответ 3

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

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

Ответ 4

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

global a

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