L'utilisation de variables globales dans une fonction
comment créer ou utiliser une variable globale dans une fonction?
Si je créer 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?
18 réponses
vous pouvez utiliser une variable globale dans d'autres fonctions en la déclarant comme global
dans chaque fonction qui lui attribue:
globvar = 0
def set_globvar_to_one():
global globvar # Needed to modify global copy of globvar
globvar = 1
def print_globvar():
print(globvar) # No need for global declaration to read value of globvar
set_globvar_to_one()
print_globvar() # Prints 1
j'imagine que la raison en est que, puisque les variables globales sont si dangereuses, Python veut s'assurer que vous savez vraiment avec quoi vous jouez en exigeant explicitement le mot-clé global
.
Voir d'autres réponses si vous voulez partager une variable globale entre les modules.
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).
dites que vous avez un module comme celui-ci:
# sample.py
myGlobal = 5
def func1():
myGlobal = 42
def func2():
print myGlobal
func1()
func2()
vous pourriez vous attendre à ce que cela imprime 42, mais à la place il imprime 5. Comme il a déjà été mentionné, si vous ajoutez un ' global
' déclaration à func1()
, alors func2()
affichera 42.
def func1():
global myGlobal
myGlobal = 42
ce qui se passe ici , C'est que Python suppose que n'importe quel nom qui est assigné à , n'importe où dans une fonction, est local à cette fonction sauf indication contraire explicite. Si c'est seulement qui lit à partir d'un nom, et que le nom n'existe pas localement, il essaiera de chercher le nom dans n'importe quelle portée contenant (par exemple, la portée globale du module).
quand vous assignez 42 au nom myGlobal
, donc, Python crée une variable locale qui cache la variable globale du même nom. Ce local sort de la portée et est poubelle quand func1()
retourne; pendant ce temps, func2()
ne peut jamais rien voir d'autre que le nom global (non modifié). Notez que cette décision d'espace de noms se produit au moment de la compilation, pas à l'exécution -- si vous deviez lire la valeur de myGlobal
à l'intérieur de func1()
avant de lui assigner, vous obtiendriez un UnboundLocalError
, parce que Python a déjà décidé qu'il doit être une variable locale, mais il n'a pas encore eu aucune valeur associée à elle. Mais en utilisant la déclaration ' global
', vous dites à Python qu'il devrait chercher ailleurs le nom au lieu de l'attribuer localement.
(je crois que ce comportement provient en grande partie d'une optimisation des espaces de noms locaux -- sans ce comportement, la VM de Python devrait effectuer au moins trois recherches de noms chaque fois qu'un nouveau nom est assigné à l'intérieur d'un fonction (pour s'assurer que le nom n'existe pas déjà au niveau module/builtin), ce qui ralentirait considérablement une opération très courante.)
vous pouvez explorer la notion de namespaces . En Python, le module est l'endroit naturel pour global données:
chaque module a sa propre table de symboles privée, qui est utilisée comme table de symboles globale par toutes les fonctions définies dans le module. Ainsi, l'auteur d'un module peut utiliser des variables globales dans le module sans se soucier accidentelle des affrontements avec un utilisateur les variables globales. D'autre part, si vous savez ce que vous faites, vous pouvez toucher un module de variables globales avec la même notation utilisée pour désigner ses fonctions,
modname.itemname
.
une utilisation spécifique de global-in-a-module est décrite ici - how-do - i-share-global-variables-across-modules , et pour plus d'exhaustivité le contenu est partagé ici:
la façon canonique de partager l'information les modules d'un même programme doivent créer un module de configuration spécial (souvent appelé config ou cfg). Il suffit d'importer le module de configuration dans tous les modules de votre application; le module devient alors disponible sous forme de nom global. Comme il n'y a qu'une seule instance de chaque module, toute modification apportée à l'objet du module se reflète partout. Par exemple:
fichier: config.py
x = 0 # Default value of the 'x' configuration setting
fichier: mod.py
import config
config.x = 1
fichier: main.py
import config
import mod
print config.x
Python utilise un heuristique simple pour décider de quelle portée 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é mondiale, il est considéré comme local. S'il n'apparaît pas du côté gauche d'une tâche, il est supposé être global.
>>> import dis
>>> def foo():
... global bar
... baz = 5
... print bar
... print baz
... print quux
...
>>> dis.disassemble(foo.func_code)
3 0 LOAD_CONST 1 (5)
3 STORE_FAST 0 (baz)
4 6 LOAD_GLOBAL 0 (bar)
9 PRINT_ITEM
10 PRINT_NEWLINE
5 11 LOAD_FAST 0 (baz)
14 PRINT_ITEM
15 PRINT_NEWLINE
6 16 LOAD_GLOBAL 1 (quux)
19 PRINT_ITEM
20 PRINT_NEWLINE
21 LOAD_CONST 0 (None)
24 RETURN_VALUE
>>>
voir comment baz, qui apparaît sur le côté gauche d'une affectation dans foo()
, est la seule variable LOAD_FAST
.
si vous voulez 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'avez pas à l'utiliser dans tous les cas (comme quelqu'un ici le prétend incorrectement) - 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 variables globales.
cependant, si vous assignez à une nouvelle variable non déclaré comme global dans la fonction, il est implicitement déclaré comme local, et il peut éclipser n'importe quelle variable globale existante avec le même nom.
aussi, les variables globales sont utiles, contrairement à certains fanatiques de OOP qui prétendent le contraire - surtout pour les petits scripts, où OOP est exagéré.
en plus des réponses déjà existantes et pour rendre cela plus confus:
en Python, les variables qui ne sont référencées qu'à l'intérieur d'une fonction sont implicitement global . Si une variable est assignée une nouvelle valeur n'importe où dans le corps de la fonction, il est supposé être un local . Si une variable est jamais assigner une nouvelle valeur à l'intérieur de la fonction, la variable est implicitement local, et vous devez déclarer explicitement comme "global".
bien qu'un peu surprenant au début, la considération d'un moment explique ce. D'une part, exigeant mondial pour les variables assignées fournit un bar contre les effets secondaires imprévus. D'autre part, si le mondial était requis pour toutes les références globales, vous utiliseriez tous les temps. Vous devez déclarer comme globale chaque référence à un intégré fonction ou à un composant d'un module importé. Ce serait le désordre défaite l'utilité de la déclaration mondiale des effets secondaires.
Source: quelles sont les règles pour les variables locales et globales en Python? .
Si je créer une variable globale dans une fonction, comment puis-je utiliser cette variable dans une autre fonction?
nous pouvons créer un global avec la fonction suivante:
def create_global_variable():
global global_variable # must declare it to be a global first
# modifications are thus reflected on the module's global scope
global_variable = 'Foo'
écrire une fonction n'exécute pas son code. Nous appelons donc la fonction create_global_variable
:
>>> create_global_variable()
utilisant des globals sans modification
vous pouvez simplement l'utiliser, vous ne vous attendez pas à changer l'objet qu'il pointe à:
par exemple,
def use_global_variable():
return global_variable + '!!!'
et maintenant, nous pouvons utiliser la variable globale:
>>> use_global_variable()
'Foo!!!'
Modification de la variable globale à l'intérieur d'une fonction
pour pointer la variable globale vers un objet différent, vous devez à nouveau utiliser le mot-clé global:
def change_global_variable():
global global_variable
global_variable = 'Bar'
notez qu'après avoir écrit cette fonction, le code qui change n'a pas encore fonctionné:
>>> use_global_variable()
'Foo!!!'
donc après avoir appelé la fonction:
>>> change_global_variable()
nous pouvons voir que la variable globale a été changé. Le nom global_variable
pointe maintenant vers 'Bar'
:
>>> use_global_variable()
'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 quand 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 avec le même nom
si vous créez une variable locale avec le même nom, elle éclipsera une variable globale:
def use_local_with_same_name_as_global():
# bad name for a local variable, though.
global_variable = 'Baz'
return global_variable + '!!!'
>>> use_local_with_same_name_as_global()
'Baz!!!'
mais l'utilisation de cette variable locale ne change pas la variable globale:
>>> use_global_variable()
'Bar!!!'
notez que vous devez éviter d'utiliser les variables locales avec les mêmes noms que les globals à moins que vous ne sachiez précisément ce que vous faites et que vous ayez une très bonne raison de le faire. Je n'ai pas encore rencontré une telle raison.
avec l'exécution parallèle, les variables globales peuvent causer des résultats inattendus si vous ne comprenez pas ce qui se passe. Voici un exemple d'utilisation d'une variable globale dans le traitement multiple. Nous pouvons clairement voir que chaque processus fonctionne avec sa propre copie de la variable:
import multiprocessing
import os
import random
import sys
import time
def worker(new_value):
old_value = get_value()
set_value(random.randint(1, 99))
print('pid=[{pid}] '
'old_value=[{old_value:2}] '
'new_value=[{new_value:2}] '
'get_value=[{get_value:2}]'.format(
pid=str(os.getpid()),
old_value=old_value,
new_value=new_value,
get_value=get_value()))
def get_value():
global global_variable
return global_variable
def set_value(new_value):
global global_variable
global_variable = new_value
global_variable = -1
print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after set_value(), get_value() = [%s]' % get_value())
processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))
sortie:
before set_value(), get_value() = [-1]
after set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]
vous devez référencer la variable globale dans chaque fonction que vous voulez utiliser.
comme suit:
var = "test"
def printGlobalText():
global var #wWe are telling to explicitly use the global version
var = "global from printGlobalText fun."
print "var from printGlobalText: " + var
def printLocalText():
#We are NOT telling to explicitly use the global version, so we are creating a local variable
var = "local version from printLocalText fun"
print "var from printLocalText: " + var
printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""
Ce que vous dites est d'utiliser la méthode comme ceci:
globvar = 5
def f():
var = globvar
print(var)
f() # Prints 5
Mais la meilleure façon est d'utiliser la variable globale comme ceci:
globavar = 5
def f():
global globvar
print(globvar)
f() #prints 5
donnent tous les deux la même sortie.
il s'avère Que la réponse est toujours simple.
voici un petit module d'échantillon avec une façon simple de le montrer dans une main
définition:
def five(enterAnumber,sumation):
global helper
helper = enterAnumber + sumation
def isTheNumber():
return helper
Voici comment le montrer dans un main
définition:
import TestPy
def main():
atest = TestPy
atest.five(5,8)
print(atest.isTheNumber())
if __name__ == '__main__':
main()
ce code simple fonctionne exactement comme cela, et il s'exécutera. J'espère que cela aide.
vous ne stockez pas réellement le global dans une variable locale, créant simplement une référence locale à l'objet auquel votre référence globale originale se réfère. Rappelez-vous que presque tout en Python est un nom qui se réfère à un objet, et que rien n'est copié dans les opérations habituelles.
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 un nouveau variable locale à la place (par exemple, avec quelque chose comme la commande 'var' en JavaScript). Puisque les variables locales sont plus communes que les variables globales dans n'importe quel système sérieux et non trivial, le système de Python a plus de sens dans la plupart des cas.
vous pourrait avoir un langage qui a tenté de deviner, en utilisant une variable globale si elle existait ou en créant une variable locale si elle n'existait pas. Toutefois, cela serait très sujet à des erreurs. Par exemple, l'importation de un autre module pourrait introduire par inadvertance une variable globale de ce nom, modifiant le comportement de votre programme.
essayez ceci:
def x1():
global x
x = 6
def x2():
global x
x = x+1
print x
x = 5
x1()
x2() # output --> 7
après et en tant qu'ajout, utilisez un fichier pour contenir toutes les variables globales toutes déclarées localement et ensuite 'importer sous':
fichier initval.py
Stocksin = 300
Prices = []
fichier getstocks.py
import initval as iv
Def getmystocks ():
iv.Stocksin = getstockcount ()
Def getmycharts ():
For ic in range (0,iv.Stocksin):
.....
L'écriture aux éléments explicites d'un tableau global n'a apparemment pas besoin de la déclaration globale, Bien que l'écriture à lui "de gros" a cette exigence:
import numpy as np
hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])
def func1():
global hostValue # mandatory, else local.
hostValue = 2.0
def func2():
global hostValue # mandatory, else UnboundLocalError.
hostValue += 1.0
def func3():
global hostArray # mandatory, else local.
hostArray = np.array([14., 15.])
def func4(): # no need for globals
hostArray[0] = 123.4
def func5(): # no need for globals
hostArray[1] += 1.0
def func6(): # no need for globals
hostMatrix[1][1] = 12.
def func7(): # no need for globals
hostMatrix[0][0] += 0.33
func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix
dans le cas où vous avez une variable locale avec le même nom, vous pourriez vouloir utiliser la globals()
fonction .
globals()['your_global_var'] = 42
référencez l'espace de noms de classe où vous voulez que le changement apparaisse.
dans cet exemple, runner utilise max à partir du fichier config. Je veux que mon test change la valeur de max quand runner l'utilise.
main/config.py
max = 15000
main/runner.py
from main import config
def check_threads():
return max < thread_count
tests/runner_test.py
from main import runner # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
def test_threads(self):
runner.max = 0 # <----- 2. set global
check_threads()
j'ajoute ceci car je ne l'ai vu dans aucune des autres réponses et il pourrait être utile pour quelqu'un luttant avec quelque chose de similaire. La fonction globals () retourne un dictionnaire de symboles global mutable où vous pouvez "magiquement" rendre les données disponibles pour le reste de votre code. Par exemple:
from pickle import load
def loaditem(name):
with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
globals()[name] = load(openfile)
return True
et
from pickle import dump
def dumpfile(name):
with open(name+".dat", "wb") as outfile:
dump(globals()[name], outfile)
return True
vous permettra simplement de décharger/charger des variables hors et dans l'espace de noms global. Super pratique, pas de mussels, Non agitation. Je suis sûr que c'est python 3 seulement.