65 votes

Python écrasant les variables dans les fonctions imbriquées

Supposons que j'ai le code python suivant :

 def outer():
    string = ""
    def inner():
        string = "String was changed by a nested function!"
    inner()
    return string

Je veux qu'un appel à external() renvoie "La chaîne a été modifiée par une fonction imbriquée!", mais j'obtiens "". J'en conclus que Python pense que la ligne string = "string was changed by a nested function!" est une déclaration d'une nouvelle variable locale à inner(). Ma question est : comment dire à Python qu'il doit utiliser la chaîne external() ? Je ne peux pas utiliser le global , car la chaîne n'est pas globale, elle vit simplement dans une portée externe. Des idées ?

73voto

Sven Marnach Points 133943

Dans Python 3.x, vous pouvez utiliser le mot-clé nonlocal

 def outer():
    string = ""
    def inner():
        nonlocal string
        string = "String was changed by a nested function!"
    inner()
    return string

Dans Python 2.x, vous pouvez utiliser une liste avec un seul élément et écraser cet élément unique :

 def outer():
    string = [""]
    def inner():
        string[0] = "String was changed by a nested function!"
    inner()
    return string[0]

27voto

Scott Crunketon Points 30

Vous pouvez également contourner ce problème en utilisant les attributs de fonction :

 def outer():
    def inner():
        inner.string = "String was changed by a nested function!"
    inner.string = ""
    inner()
    return inner.string

Clarification : cela fonctionne à la fois en python 2.x et 3.x.

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