2017-05-08 1 views
5

Dans mon programme, je ne voulais une variable globale que dans certaines circonstances. Dites qu'il ressemble à ceci:Comment 'global' se comporte-t-il sous une instruction if?

a = 0 
def aa(p): 
    if p: 
     global a 
    a = 1 
    print("inside the function " + str(a)) 


print(a) 
aa(False) 
print("outside the function " + str(a)) 

j'attendais que le résultat soit:

0 
inside the function 1 
outside the function 0 

Cependant, il est avéré être:

0 
inside the function 1 
outside the function 1 

Alors, je me disais: « D'accord peut-être que le compilateur Python rend la variable globale chaque fois qu'il voit le mot-clé 'global', peu importe où il se trouve ". Est-ce ainsi que Python fonctionne avec les variables globales? Suis-je un malentendu?

Répondre

5

Oui, vous comprenez bien les choses.

L'instruction global n'est pas évaluée lors de l'exécution. C'est vraiment une directive à l'analyseur qui lui dit essentiellement de traiter tous les identifiants listés (a ici) comme se référant à la portée globale. À partir des documents sur the global statement:

L'instruction globale est une déclaration qui s'applique à l'ensemble du bloc de code actuel. Cela signifie que les identifiants listés doivent être interprétés comme globaux.

Il continue alors à dire comment est global est vraiment une directive :

Note du programmeur: global est une directive à l'analyseur.

Son utilisation conditionnelle ne fait aucune différence: sa présence a déjà été détectée dans la phase d'analyse et, par conséquent, l'octet code généré pour saisir les noms a déjà été mis à regarder dans la portée globale (avec LOAD/STORE GLOBAL). C'est pourquoi, si vous dis.dis une fonction contenant une instruction global, vous ne verrez aucun code-octet pertinent pour global. En utilisant une fonction stupide:

from dis import dis 
def foo(): 
    "I'm silly" 
    global a 

dis(foo) 
    2   0 LOAD_CONST    0 (None) 
       2 RETURN_VALUE 

Rien n'est généré pour global a car les informations qu'il fournit a déjà été utilisé!