Comment créer ou utiliser une variable globale dans une fonction?
Si je crée une variable globale dans une fonction, comment puis-je utiliser cette variable globale dans une autre fonction? Dois-je stocker la variable globale dans une variable locale de la fonction qui a besoin de son accès?
python
global-variables
scope
user46646
la source
la source
global
mot-clé est que les globaux sont dangereux. C'est plutôt parce que le langage ne vous oblige pas à déclarer explicitement des variables et suppose automatiquement qu'une variable que vous affectez a une portée de fonction, sauf indication contraire. Leglobal
mot-clé est le moyen qui est fourni pour le dire autrement.f2()
changement d'étatf3()
peut-il faire quelque chose d'inattendu maintenant? Les fonctions peuvent maintenant fonctionner indépendamment de l'état du programme externe.Si je comprends bien votre situation, ce que vous voyez est le résultat de la façon dont Python gère les espaces de noms locaux (fonction) et globaux (module).
Disons que vous avez un module comme celui-ci:
Vous pouvez vous attendre à ce que cela imprime 42, mais à la place, il imprime 5. Comme cela a déjà été mentionné, si vous ajoutez une
global
déclaration ' ' àfunc1()
, alorsfunc2()
imprimera 42.Ce qui se passe ici, c'est que Python suppose que tout nom attribué à , n'importe où dans une fonction, est local à cette fonction, sauf indication contraire explicite. S'il ne lit qu'à partir d'un nom et que le nom n'existe pas localement, il essaiera de rechercher le nom dans toutes les étendues contenant (par exemple la portée globale du module).
Par
myGlobal
conséquent, lorsque vous attribuez 42 au nom , Python crée une variable locale qui associe la variable globale du même nom. Ce local sort du cadre et est récupéré lors dufunc1()
retour; en attendant,func2()
ne peut jamais voir autre chose que le nom global (non modifié). Notez que cette décision d'espace de noms se produit au moment de la compilation, pas au moment de l'exécution - si vous deviez lire la valeur demyGlobal
insidefunc1()
avant de l'affecter, vous obtiendriez unUnboundLocalError
, car Python a déjà décidé que ce devait être une variable locale mais elle n'a pas encore eu de valeur associée. Mais en utilisant l'global
instruction ' ', vous dites à Python qu'il doit chercher ailleurs le nom au lieu de lui attribuer localement.(Je crois que ce comportement provient en grande partie d'une optimisation des espaces de noms locaux - sans ce comportement, la machine virtuelle de Python devrait effectuer au moins trois recherches de nom chaque fois qu'un nouveau nom est attribué à l'intérieur d'une fonction (pour garantir que le nom ne l'a pas fait) existent déjà au niveau module / intégré), ce qui ralentirait considérablement une opération très courante.)
la source
MyGlobal = 5
x
c'est local est différent de vérifier au moment de l'exécution si le nom local était lié à une valeur avant d'être utilisé la première fois.MY_GLOBAL = 5
. Voir le Guide de style pour le code Python .Vous voudrez peut-être explorer la notion d' espaces de noms . En Python, le module est le lieu naturel pour les données globales :
Une utilisation spécifique de global-in-a-module est décrite ici - Comment partager des variables globales entre modules? , et pour être complet, le contenu est partagé ici:
la source
config.x
puis-je m'en débarrasser? Je suis venu avecx = lambda: config.x
et j'ai ensuite la nouvelle valeurx()
. pour une raison quelconque, l'avoira = config.x
ne fait pas l'affaire pour moi.from config import x
résout-il cela?Python utilise une heuristique simple pour décider de l'étendue à partir de laquelle il doit charger une variable, entre local et global. Si un nom de variable apparaît sur le côté gauche d'une affectation, mais n'est pas déclaré global, il est supposé être local. S'il n'apparaît pas sur le côté gauche d'une affectation, il est supposé être global.
Voyez comment baz, qui apparaît sur le côté gauche d'une affectation dans
foo()
, est la seuleLOAD_FAST
variable.la source
for
boucle et le nom après les instructionsas
inwith
etexcept
sont également liés à.as
dans uneexcept
clause, ce n'était pas évident pour moi. Mais il est automatiquement supprimé pour économiser de la mémoire.as ...
cible dans le gestionnaire d'exceptions.Si vous souhaitez faire référence à une variable globale dans une fonction, vous pouvez utiliser le mot clé global pour déclarer quelles variables sont globales. Vous n'êtes pas obligé de l'utiliser dans tous les cas (comme quelqu'un le prétend ici à tort) - si le nom référencé dans une expression ne peut pas être trouvé dans la portée locale ou les portées dans les fonctions dans lesquelles cette fonction est définie, il est recherché parmi les globaux variables.
Cependant, si vous attribuez à une nouvelle variable non déclarée comme globale dans la fonction, elle est implicitement déclarée comme locale, et elle peut occulter toute variable globale existante avec le même nom.
En outre, les variables globales sont utiles, contrairement à certains fanatiques de POO qui prétendent le contraire - en particulier pour les petits scripts, où la POO est exagérée.
la source
Nous pouvons créer un global avec la fonction suivante:
L'écriture d'une fonction n'exécute pas réellement son code. Nous appelons donc la
create_global_variable
fonction:Utiliser des globaux sans modification
Vous pouvez simplement l'utiliser, tant que vous ne vous attendez pas à changer vers quel objet il pointe:
Par exemple,
et maintenant nous pouvons utiliser la variable globale:
Modification de la variable globale depuis l'intérieur d'une fonction
Pour pointer la variable globale vers un autre objet, vous devez réutiliser le mot clé global:
Notez qu'après avoir écrit cette fonction, le code qui la modifie n'a toujours pas été exécuté:
Donc, après avoir appelé la fonction:
nous pouvons voir que la variable globale a été modifiée. Le
global_variable
nom pointe désormais sur'Bar'
:Notez que "global" en Python n'est pas vraiment global - c'est seulement global au niveau du module. Il n'est donc disponible que pour les fonctions écrites dans les modules dans lesquels il est global. Les fonctions se souviennent du module dans lequel elles sont écrites, donc lorsqu'elles sont exportées dans d'autres modules, elles regardent toujours dans le module dans lequel elles ont été créées pour trouver des variables globales.
Variables locales du même nom
Si vous créez une variable locale du même nom, elle éclipsera une variable globale:
Mais l'utilisation de cette variable locale mal nommée ne change pas la variable globale:
Notez que vous devez éviter d'utiliser les variables locales avec les mêmes noms que les globales, sauf si vous savez précisément ce que vous faites et que vous avez une très bonne raison de le faire. Je n'ai pas encore rencontré une telle raison.
On obtient le même comportement en classe
Un commentaire de suivi demande:
Ici, je démontre que nous obtenons le même comportement dans les méthodes que dans les fonctions régulières:
Et maintenant:
Mais je suggère qu'au lieu d'utiliser des variables globales, vous utilisez des attributs de classe, pour éviter d'encombrer l'espace de noms du module. Notez également que nous n'utilisons pas d'
self
arguments ici - il peut s'agir de méthodes de classe (pratiques si la mutation de l'attribut de classe de l'cls
argument habituel ) ou de méthodes statiques (nonself
oucls
).la source
En plus des réponses déjà existantes et pour rendre cela plus confus:
Source: Quelles sont les règles pour les variables locales et globales en Python? .
la source
Avec une exécution parallèle, les variables globales peuvent provoquer des résultats inattendus si vous ne comprenez pas ce qui se passe. Voici un exemple d'utilisation d'une variable globale dans le cadre du multitraitement. Nous pouvons clairement voir que chaque processus fonctionne avec sa propre copie de la variable:
Production:
la source
Ce que vous dites, c'est d'utiliser la méthode comme ceci:
Mais la meilleure façon est d'utiliser la variable globale comme ceci:
Les deux donnent la même sortie.
la source
Il s'avère que la réponse est toujours simple.
Voici un petit exemple de module avec un moyen simple de l'afficher dans une
main
définition:Voici comment l'afficher dans une
main
définition:Ce code simple fonctionne comme ça, et il s'exécutera. J'espère que ça aide.
la source
global_vars
et initialise les données dansinit_global_vars
celui qui est appelé dans le script de démarrage. Ensuite, je crée simplement une méthode d'accesseur pour chaque var globale définie. J'espère pouvoir voter à plusieurs reprises! Merci Peter!Vous devez référencer la variable globale dans chaque fonction que vous souhaitez utiliser.
Comme suit:
la source
Vous ne stockez pas réellement le global dans une variable locale, vous créez simplement une référence locale au même objet auquel votre référence globale d'origine fait référence. N'oubliez pas que presque tout en Python est un nom faisant référence à un objet, et rien n'est copié en fonctionnement habituel.
Si vous n'aviez pas à spécifier explicitement quand un identifiant devait se référer à un global prédéfini, alors vous auriez probablement à spécifier explicitement quand un identifiant est une nouvelle variable locale à la place (par exemple, avec quelque chose comme la commande 'var' vu en JavaScript). Étant donné que les variables locales sont plus courantes que les variables globales dans tout système sérieux et non trivial, le système de Python a plus de sens dans la plupart des cas.
Vous pourriez avoir un langage qui tenterait de deviner, en utilisant une variable globale si elle existait ou en créant une variable locale si ce n'était pas le cas. Cependant, ce serait très sujet aux erreurs. Par exemple, l'importation d'un autre module pourrait introduire par inadvertance une variable globale de ce nom, modifiant le comportement de votre programme.
la source
Essaye ça:
la source
Si vous avez une variable locale du même nom, vous pouvez utiliser la
globals()
fonction .la source
Après et en tant qu'add-on, utilisez un fichier pour contenir toutes les variables globales toutes déclarées localement, puis
import as
:Fichier initval.py :
Fichier getstocks.py :
la source
import ... as ...
? Pourquoi pas justeimport ...
?global
:-) => +1 :-) Merci de modifier votre réponse pour clarifier ces interrogations que d'autres personnes peuvent également avoir. ViveL'écriture dans des éléments explicites d'un tableau global n'a apparemment pas besoin de la déclaration globale, bien que l'écriture "en gros" ait cette exigence:
la source
J'ajoute cela car je ne l'ai vu dans aucune des autres réponses et cela pourrait être utile pour quelqu'un aux prises avec quelque chose de similaire. La
globals()
fonction renvoie un dictionnaire de symboles globaux mutable où vous pouvez "magiquement" rendre les données disponibles pour le reste de votre code. Par exemple:et
Vous permettra simplement de vider / charger des variables hors et dans l'espace de noms global. Super pratique, pas de bruit, pas de chichi. Je suis sûr que ce n'est que Python 3.
la source
globals()
renvoie toujours les globaux disponibles dans le contexte local, donc une mutation ici peut ne pas se refléter dans un autre module.Référencez l'espace de noms de classe où vous souhaitez que la modification apparaisse.
Dans cet exemple, le coureur utilise max à partir de la configuration du fichier. Je veux que mon test change la valeur de max lorsque le coureur l'utilise.
main / config.py
main / runner.py
tests / runner_test.py
la source
Les globaux vont bien - sauf avec le multitraitement
Les globaux liés au multitraitement sur différentes plates-formes / environnements, comme Windows / Mac OS d'un côté et Linux de l'autre, sont gênants.
Je vais vous montrer cela avec un exemple simple soulignant un problème que j'ai rencontré il y a quelque temps.
Si vous voulez comprendre pourquoi les choses sont différentes sous Windows / MacOs et Linux, vous devez savoir cela, le mécanisme par défaut pour démarrer un nouveau processus sur ...
Ils sont différents dans l'allocation de mémoire et l'initialisation ... (mais je n'entre pas dans le détail ici).
Jetons un œil au problème / exemple ...
les fenêtres
Si vous exécutez cela sur Windows (et je suppose aussi sur MacOS), vous obtenez la sortie suivante ...
Linux
Si vous exécutez ceci sur Linux, vous obtenez à la place ce qui suit.
la source