2009-05-30 8 views
49

J'ai beaucoup de mal à comprendre les règles de portée de Python.Pourquoi l'affectation à mes variables globales ne fonctionne-t-elle pas en Python?

Avec le script suivant:

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() 

Donne l'inattendu (pour moi) sortie:

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

Où j'attendre la dernière impression de la valeur d'un à 42, non 7. Que manque-t-il aux règles de portée de Python pour la portée des variables globales?

Répondre

97

Les variables globales sont spéciales. Si vous essayez d'affecter à une variable a = value à l'intérieur d'une fonction, elle crée une nouvelle variable locale dans la fonction, même s'il existe une variable globale avec le même nom. Pour accéder à la place la variable globale, ajoutez une global statement dans la fonction:

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

Voir aussi Naming and binding pour une explication détaillée de nommage et des règles contraignantes de Python.

+12

* (mot grossier) * python – theonlygusti

11

L'astuce pour comprendre cela est que lorsque vous affectez à une variable, en utilisant =, vous le déclarez également comme une variable locale. Ainsi, au lieu de changer la valeur de la variable globale a, setA (valeur) définit une variable locale (qui s'appelle a) à la valeur transmise.

Cela devient plus évident si vous essayez d'imprimer la valeur d'un au début de seta (valeur) comme ceci:

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

Si vous essayez d'exécuter ce Python vous donnera une erreur utile:

 
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 

cela nous dit que Python a décidé que le La fonction setA (value) a une variable locale appelée a, qui est ce que vous modifiez quand vous ass ign à lui dans la fonction. Si vous n'attribuez pas à a dans la fonction (comme avec printA()) alors Python utilise la variable globale A.

Pour marquer une variable comme globale, vous devez utiliser le mot-clé global dans Python, dans la portée que vous voulez utiliser la variable globale. Dans ce cas, cela correspond à la fonction setA (value). Ainsi, le script devient:

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() 

Celui-ci dit plus Python que lorsque vous utilisez l'une variable dans la fonction Seta (valeur) que vous parlez de la variable globale, et non pas une variable locale.

2

Python n'a pas de concept de variables comme les autres langages. Vous avez des objets qui sont "quelque part" et vous avez des références à ces objets. = est utilisé pour affecter ces objets aux références dans l'espace de noms actuel.

Vous créez un nom a dans l'espace de nom de la fonction setA qui fait référence à l'objet auquel se réfère la valeur.

1

dans la fonction, un est traitée comme une variable locale, vous devez définir

global a

dans la fonction

Questions connexes