2010-05-06 8 views
1

S'il vous plaît voir le code suivant:Les variables globales Mutable ne sont pas masquées dans les fonctions Python, n'est-ce pas?

def good(): 
    foo[0] = 9   # why this foo isn't local variable who hides the global one 

def bad(): 
    foo = [9, 2, 3] # foo is local, who hides the global one 

for func in [good, bad]: 
    foo = [1,2,3] 

    print('Before "{}": {}'.format(func.__name__, foo)) 
    func() 
    print('After "{}": {}'.format(func.__name__, foo)) 

Le résultat est comme ci-dessous:

# python3 foo.py 
Before "good": [1, 2, 3] 
After "good": [9, 2, 3] 
Before "bad" : [1, 2, 3] 
After "bad" : [1, 2, 3] 

Répondre

7

Parce que vous n'êtes pas mise foo, vous obtenez quelque chose dans foo (foo [0] pour être exact). Dans bad, vous créez une nouvelle variable foo. En good vous faites quelque chose comme foo.set(0, 9) (mettre l'article 0 à la valeur 9). Qui est en utilisant une variable, et ne définissant pas un nouveau nom.

+0

Je suppose que vous avez raison. Pas de paramètres, pas de nouveau nom. – aXqd

+0

Je suppose, mais pourquoi différer la logique entre le réglage et l'utilisation? Si c'est bien, vous devez également déclarer global foo, n'est-ce pas plus cohérent et empêcher l'utilisateur de tirer son propre pied? – liang

0

Les variables se tourneront d'abord vers leur portée interne puis vers les étendues externes en python. Par exemple:

FOO = 'global' 

def printfoo(): 
    print FOO 
# prints 'global' 

def printfoolocal(): 
    FOO = 'local' 
    print FOO 
# prints 'local' 

Si vous souhaitez modifier une variable scope globalement, vous devez utiliser le mot-clé global

def modifyfoo(): 
    global FOO 
    FOO = 'modified' 
print FOO 
# prints 'modified' 
+0

Je connais ce comportement, juste curieux de connaître les différences dans les deux cas. Je pense que @extraneon a répondu à ma question. Merci quand même. – aXqd

0

Pour faire simple, python premier coup d'oeil dans les variables locales et après dans les globaux. (Pour lire ou créer une variable)

Donc, dans le bon sens, vous prenez la variable foo: Aucune variable foo locale et une variable foo globale => vous prenez la variable globale et vous la modifiez.

En cas de problème, vous créez une nouvelle variable (locale), de sorte que la variable globale n'est pas modifiée.

Vous pouvez spécifier qu'une variable est globale avec le mot-clé global:

def good2(): 
    global foo 
    foo = [9, 2, 3] 
+0

> "Donc, en bien, vous prenez la variable foo: Aucune variable foo locale et une variable globale foo => vous prenez la variable globale et vous la modifiez." Ma question est exactement pourquoi ce comportement ne se produirait-il pas en 'mauvais'. Quelles sont les règles ici? – aXqd

0

Si, comme bon, vous voulez remplacer le contenu de la liste foo, alors vous pouvez attribuer à une tranche de l'ensemble liste comme:

def good2(): 
    foo[:] = [9, 2, 3] 

Tout comme où good affecté à un élément de la liste, cela remplace tout le contenu.

Dans bad vous liez une nouvelle liste au nom foo.

+0

Oui, 'good2' devrait être le même que 'good' – aXqd

Questions connexes