Question

Je vais avoir du mal à comprendre terribles essayer des règles de cadrage 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 l'inattendu (pour moi) de sortie:

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

Où j'attends la dernière impression de la valeur d'un être 42, pas 7. Qu'est-ce que je manque au sujet des règles de portée en Python pour la détermination de la portée des variables globales?

Était-ce utile?

La solution

Les variables globales sont spéciales. Si vous essayez d'attribuer à une a = value variable à l'intérieur d'une fonction, il crée une nouvelle variable locale dans la fonction, même s'il y a une variable globale du même nom. Pour accéder à la place la variable globale, ajoutez une instruction global à l'intérieur du 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 et binding pour une explication détaillée de la dénomination de Python et des règles contraignantes.

Autres conseils

L'astuce pour comprendre est que lorsque vous attribuez à une variable, en utilisant =, vous déclarez également comme une variable locale. Ainsi, au lieu de changer la valeur de la variable globale a, Seta (valeur) définit en fait une variable locale (ce qui arrive à être appelé 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 la fonction Seta (valeur) a une variable locale appelée, qui est ce que vous modifiez lorsque vous attribuez dans la fonction. Si vous n'attribuez pas à la fonction (comme Printa ()) puis Python utilise la variable globale A.

Pour marquer une variable globale que vous devez utiliser le mot-clé global en Python, dans le cadre que vous souhaitez utiliser la variable globale . Dans ce cas, qui est dans la fonction Seta (valeur). 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()

un ajout de ligne indique 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.

Python ne dispose pas d'un concept de variables telles que d'autres langues. Vous avez des objets qui sont « quelque part » et vous avez des références à ces objets. = Permet d'affecter ces objets à des références dans le courant espace de noms.

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

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

  

global

dans la fonction

L'exécution d'une fonction présente une nouvelle table de symbole utilisé pour les variables locales de la fonction. Plus précisément, toutes les attributions variables en fonction de stocker la valeur dans la table de symboles locaux; tandis que les références variables d'abord regarder dans la table des symboles local, puis dans les tableaux de symboles locaux enserrant fonctions, puis dans la table de symboles globale, et enfin dans la table des noms intégrés. Ainsi, les variables globales ne peuvent pas être directement attribué une valeur dans une fonction (à moins que le nom dans un communiqué global), bien qu'ils puissent être référencés.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top