web-dev-qa-db-fra.com

Pourquoi les fonctions imbriquées peuvent accéder aux variables à partir des fonctions externes, mais ne sont pas autorisées à les modifier

Dans le 2ème cas ci-dessous, Python essaie de rechercher une variable locale. Quand il n'en trouve pas, pourquoi ne peut-il pas chercher dans la portée externe comme il le fait pour le 1er cas?

Cela recherche x dans la portée locale, puis la portée extérieure:

def f1():
    x = 5
    def f2():
         print x

Cela donne local variable 'x' referenced before assignment Erreur:

def f1():
    x = 5
    def f2():
        x+=1

Je ne suis pas autorisé à modifier la signature de la fonction f2 () donc je ne peux pas passer et retourner des valeurs de x. Cependant, j'ai besoin d'un moyen de modifier x. Existe-t-il un moyen de dire explicitement Python pour rechercher un nom de variable dans la portée externe (quelque chose de similaire au mot clé global)?

Version Python: 2.7

64
Dhara
def f1():
    x = { 'value': 5 }
    def f2():
        x['value'] += 1

La solution consiste à utiliser un objet modifiable et à mettre à jour les membres de cet objet. La liaison de noms est parfois délicate en Python.

52
Tom Whittock

En Python 3.x c'est possible:

def f1():
        x = 5
        def f2():
                nonlocal x
                x+=1
        return f2

Le problème et une solution, pour Python 2.x également, sont donnés dans this post. De plus, veuillez lire PEP 3104 = pour plus d'informations à ce sujet.

69
hochl