Est-il possible de modifier les variables en python qui est à l'extérieur, mais pas global, de la portée?
Donné le code suivant:
def A() :
b = 1
def B() :
# I can access 'b' from here.
print( b )
# But can i modify 'b' here? 'global' and assignment will not work.
B()
A()
Pour le code de B()
variable de fonction b
est à l'extérieur de la portée, mais pas dans la portée globale. Est-il possible de modifier b
variable de l'intérieur B()
fonction? Certes, je peux le lire à partir d'ici et print()
, mais comment le modifier?
- Python 3 ou 2 ?
- Désolé, bien sûr 2.7 :). Pour python 3 règles de portée a changé.
- Vous pouvez aussi longtemps que
b
est mutable. Une cession àb
masque l'extérieur de la portée. - C'est l'un de Python embarras que
nonlocal
n'a pas été portée à 2.x. C'est une partie intrinsèque de soutien de fermeture.
Vous devez vous connecter pour publier un commentaire.
Python 3.x a la
non
mot clé. Je pense que cela ne ce que vous voulez, mais je ne suis pas sûr si vous êtes en cours d'exécution python 2 ou 3.Pour python 2, j'ai l'habitude de simplement utiliser un objet mutable (comme une liste, ou dict), et muter la valeur au lieu de les réaffecter.
exemple:
Sorties:
class nonlocal: pass
à l'extérieur de la portée. Puisnonlocal.x
peut être affecté dans l'intérieur de la portée.SyntaxError
. Peut-êtreNonLocal
?outer
pourrait fonctionner...Nonlocal
? 🙂Vous pouvez utiliser une classe vide de tenir une temporaire de la portée. C'est comme la mutable mais un peu plus joli.
Ce rendements suivants interactive sortie:
Je suis un peu en Python, mais j'ai lu un peu à ce sujet. Je crois que le mieux que vous allez obtenir est similaire à Java contourner ce problème, qui est d'envelopper votre extérieur variable dans une liste.
Edit: je suppose que c'était probablement vrai avant de Python 3. Ressemble
nonlocal
est votre réponse.Pas vous ne pouvez pas, au moins de cette manière.
Parce que le "jeu de l'opération" permettra de créer un nouveau nom dans le champ d'application actuel, qui couvre l'extérieur.
Pour tous ceux qui cherchent à ce que beaucoup plus tard sur un plus sûr, mais plus lourd de la solution de contournement est. Sans besoin de passer des variables comme paramètres.
Je ne pense pas que vous devrait envie de le faire. Les fonctions qui peuvent changer les choses dans leur joignant contexte sont dangereux, que ce contexte peut être écrit sans la connaissance de la fonction.
On pourrait le rendre explicite, soit en apportant des B une méthode publique et C une méthode privée dans une classe (la meilleure façon sans doute); ou en utilisant une mutable type comme une liste et de les transmettre explicitement à C:
nonlocal
mot-clé - mais c'est à vous de l'utiliser avec une grande prudence.Vous pouvez, mais vous aurez à utiliser le mondial de tresorerie (pas vraiment une bonne solution, comme toujours lors de l'utilisation de variables globales, mais il fonctionne):
Je ne sais pas si il y a un attribut d'une fonction qui donne la
__dict__
de l'espace extérieur de la fonction lors de cet espace extérieur n'est pas l'espace mondial == le module, ce qui est le cas lorsque la fonction est une fonction imbriquée, en Python 3.Mais en Python 2, pour autant que je sais, il n'y a pas un tel attribut.
De sorte que la seule possibilité de faire ce que vous voulez, c'est:
1) à l'aide d'un objet mutable, comme dit par d'autres
2)
résultat
.
Nota
La solution de Cédric Julien a un inconvénient:
résultat
Le mondial b après l'exécution de
A()
a été modifié et il est peut-être pas whished doncC'est le cas seulement si il existe un objet avec un identifiant b dans l'espace de noms global