76 votes

Pourquoi l'assignation à mes variables globales ne fonctionne pas en Python ?

J'ai beaucoup de mal à comprendre les règles de scoping de 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 le résultat inattendu (pour moi) de :

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

Où je m'attendrais à ce que la dernière impression de la valeur de a soit 42, et non 7. Qu'est-ce qui m'échappe dans les règles de Python concernant la portée des variables globales ?

158voto

Adam Rosenfield Points 176408

Les variables globales sont spéciales. Si vous essayez d'assigner à une variable a = value à l'intérieur d'une fonction, elle crée une nouvelle variable locale à l'intérieur de la fonction, même s'il existe une variable globale portant le même nom. Pour accéder à la variable globale, il faut ajouter un global déclaration à l'intérieur de 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 Nommer et relier pour une explication détaillée des règles de dénomination et de liaison de Python.

0 votes

Je veux faire quelque chose comme ceci a = a + value . la même erreur se produit. Y a-t-il un moyen de contourner ce problème ?

15voto

Free Wildebeest Points 1548

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

Cela devient plus évident si vous essayez d'imprimer la valeur de a au début de setA(value) 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 de l'exécuter, 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 indique que Python a décidé que la fonction setA(value) possède une variable locale appelée a, qui est ce que vous modifiez lorsque vous l'assignez dans la fonction. Si vous n'assignez pas à a dans la fonction (comme avec printA()), Python utilise la variable globale A.

Pour marquer une variable comme globale, vous devez utiliser le mot-clé global en Python, dans la portée où vous voulez utiliser la variable globale . Dans ce cas, c'est à l'intérieur de la fonction setA(valeur). Donc 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()

Cet ajout d'une ligne indique à Python que lorsque vous utilisez la variable a dans la fonction setA(value), vous parlez de la variable globale et non d'une variable locale.

3voto

appusajeev Points 394

À l'intérieur de la fonction, a est traitée comme une variable locale, vous devez définir

mondial a

à l'intérieur de la fonction avant de l'utiliser à l'intérieur de la méthode, même si vous l'aviez défini à l'extérieur de la méthode.

2voto

DasIch Points 1595

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

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

0voto

Nilesh Jain Points 96

L'exécution d'une fonction introduit une nouvelle table de symboles utilisée pour les variables locales de la fonction. Plus précisément, toutes les affectations de variables dans une fonction enregistrent la valeur dans la table des symboles locaux, tandis que les références de variables sont d'abord recherchées dans la table des symboles locaux, puis dans les tables des symboles locaux des fonctions englobantes, puis dans la table des symboles globaux, et enfin dans la table des noms intégrés. Ainsi, les variables globales ne peuvent pas se voir attribuer directement une valeur dans une fonction (sauf si elles sont nommées dans une instruction globale), mais elles peuvent être référencées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X