Question

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 nécessite son accès?

Était-ce utile?

La solution

Vous pouvez utiliser une variable globale dans d'autres fonctions en la déclarant comme global dans chaque fonction qui l'assigne:

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, les variables globales étant si dangereuses, Python veut s'assurer que vous savez vraiment ce à quoi vous jouez en demandant explicitement le mot clé global .

Voir les autres réponses si vous souhaitez partager une variable globale entre les modules.

Autres conseils

Si je comprends bien votre situation, vous constatez que Python gère les espaces de noms locaux (fonction) et globaux (modules).

Dites que vous avez un module comme celui-ci:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Vous pouvez vous attendre à ce que ceci soit imprimé 42, mais à la place, il en imprime 5. Comme cela a déjà été mentionné, si vous ajoutez une déclaration ' global ' à func1 () , alors func2 () en affichera 42.

def func1():
    global myGlobal
    myGlobal = 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 explicite du contraire. Si il ne lit que à partir d'un nom et que ce nom n'existe pas localement, il tentera de rechercher le nom dans les portées qui le contiennent (par exemple, le champ d'application global du module).

Lorsque vous attribuez le nom 42 au code myGlobal , Python crée donc une variable locale qui masque la variable globale du même nom. Cette section locale est hors de portée et est non récupérée lorsque func1 () renvoie; Pendant ce temps, func2 () ne peut jamais voir autre chose que le nom global (non modifié). Notez que cette décision d’espace de nommage a lieu au moment de la compilation, pas au moment de l’exécution. Si vous lisiez la valeur de myGlobal dans func1 () avant de l’affecter, vous ' d obtenir un UnboundLocalError , car Python a déjà décidé qu'il doit s'agir d'une variable locale, mais aucune valeur ne lui a encore été associée. Mais en utilisant l'instruction ' global ', vous indiquez à Python qu'il doit chercher le nom ailleurs, au lieu de l'attribuer localement.

(Je pense que ce problème 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é à une fonction (pour garantir que le Le nom n’existait pas déjà au niveau module / builtin), ce qui ralentirait considérablement une opération très courante.)

Vous voudrez peut-être explorer la notion des espaces de noms . En Python, le module est le lieu naturel pour global données:

  

Chaque module possède 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 des conflits accidentels avec les variables globales d'un utilisateur. D'autre part, si vous savez ce que vous faites, vous pouvez toucher les variables globales d'un module avec la même notation que celle utilisée pour faire référence à ses fonctions, modname.itemname .

Une utilisation spécifique de global-in-a-module est décrite ici - Comment partager des variables globales entre modules? , et pour plus de précision, le contenu est partagé ici:

  

Pour partager des informations entre modules au sein d'un même programme, il est de créer un module de configuration spécial (souvent appelé config ou cfg ). Importez simplement 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 module est reflétée 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 une heuristique simple pour décider de la portée à partir de laquelle charger une variable, entre local et global. Si un nom de variable apparaît à gauche d'une affectation, mais n'est pas déclaré global, il est supposé être local. S'il n'apparaît pas à gauche d'une affectation, 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 à gauche d'une assignation dans foo () , est la seule variable LOAD_FAST .

Si vous souhaitez faire référence à une variable globale dans une fonction, vous pouvez utiliser le mot clé global pour déclarer les variables globales. Vous n'êtes pas obligé de l'utiliser dans tous les cas (comme le prétend quelqu'un, à tort): si le nom référencé dans une expression est introuvable dans la ou les étendues locales dans les fonctions dans lesquelles cette fonction est définie, elle est recherchée dans la liste globale. variables.

Toutefois, si vous assignez une nouvelle variable non déclarée comme globale dans la fonction, elle est implicitement déclarée comme locale et peut occulter toute variable globale existante portant le même nom.

De plus, les variables globales sont utiles, contrairement à certains fanatiques de la POO qui affirment le contraire - en particulier pour les scripts plus petits, où la POO est excessive.

En plus des réponses déjà existantes et pour rendre ceci plus confus:

  

En Python, les variables qui ne sont référencées que dans une fonction sont    implicitement global . Si une nouvelle valeur est affectée à une variable n'importe où   dans le corps de la fonction, il est supposé être un local . Si une variable   est jamais attribué une nouvelle valeur à l'intérieur de la fonction, la variable est   implicitement local, et vous devez le déclarer explicitement comme "global".

     

Bien qu’un peu surprenant au début, un instant de réflexion explique   ce. D'un côté, requérir Global pour les variables assignées fournit   bar contre les effets secondaires inattendus. D'autre part, si global était   requis pour toutes les références globales, vous utiliseriez global   temps. Vous devez déclarer globalement chaque référence à un fichier intégré.   fonction ou à un composant d'un module importé. Ce fouillis serait   vaincre l'utilité de la déclaration globale pour identifier   effets secondaires.

Source: Quelles sont les règles pour les variables locales et globales en Python? .

  

Si je crée 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' 

L’écriture d’une fonction n’exécute pas son code. Nous appelons donc la fonction create_global_variable :

>>> create_global_variable()

Utilisation de variables globales sans modification

Vous pouvez simplement l'utiliser, tant que vous ne vous attendez pas à changer l'objet sur lequel 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 depuis une fonction

Pour pointer la variable globale vers un autre objet, vous devez utiliser à nouveau le mot clé global:

def change_global_variable():
    global global_variable
    global_variable = 'Bar'

Notez qu'après l'écriture de cette fonction, le code qui la modifie n'a toujours pas été exécuté:

>>> change_global_variable()

Donc après avoir appelé la fonction:

>>> use_global_variable()
'Bar!!!'

nous pouvons voir que la variable globale a été modifiée. Le nom variable_variable pointe maintenant sur 'Barre' :

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!!!'

Notez que " global " en Python n’est pas vraiment global - c’est seulement global au niveau du module. Donc, il n'est disponible que pour les fonctions écrites dans les modules dans lesquels il est global. Les fonctions mémorisent le module dans lequel elles sont écrites. Par conséquent, lorsqu'elles sont exportées dans d'autres modules, elles recherchent toujours le module dans lequel elles ont été créées pour rechercher des variables globales.

Variables locales du même nom

Si vous créez une variable locale portant le même nom, une variable globale sera ombragée:

<*>

Mais utiliser cette variable locale mal nommée ne change pas la variable globale:

<*>

Notez que vous devez éviter d'utiliser les variables locales portant le même nom que les variables globales, à moins de savoir précisément ce que vous faites et d'avoir 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 générer des résultats inattendus si vous ne comprenez pas ce qui se passe. Voici un exemple d'utilisation d'une variable globale dans le multitraitement. 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))

Résultat:

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]

Il se trouve que la réponse est toujours simple.

Voici un petit exemple de module permettant de l'afficher simplement dans une définition main :

def five(enterAnumber,sumation):
    global helper
    helper  = enterAnumber + sumation

def isTheNumber():
    return helper

Voici comment l'afficher dans une définition main :

import TestPy

def main():
    atest  = TestPy
    atest.five(5,8)
    print(atest.isTheNumber())

if __name__ == '__main__':
    main()

Ce code simple fonctionne exactement comme ça et s’exécutera. J'espère que ça aide.

Ce que vous dites, c'est d'utiliser la méthode suivante:

globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5

Mais le meilleur moyen consiste à utiliser la variable globale comme ceci:

globavar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5

Les deux donnent le même résultat.

Vous devez référencer la variable globale dans chaque fonction que vous souhaitez 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]
"""

Vous ne stockez pas le global dans une variable locale, vous créez simplement une référence locale au même objet que votre référence globale d'origine. N'oubliez pas que tout dans Python est un nom qui fait référence à un objet et que rien ne soit copié normalement.

Si vous n'étiez pas obligé de spécifier explicitement quand un identifiant devait faire référence à un global prédéfini, alors vous devriez probablement spécifier explicitement quand un identifiant est une nouvelle variable locale (par exemple, avec quelque chose comme ' var 'commande vue en JavaScript). Les variables locales étant plus courantes que les variables globales dans tout système sérieux et non trivial, le système de Python est plus logique dans la plupart des cas.

Vous pourriez avoir une langue 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, importer un autre module peut introduire par inadvertance une variable globale portant ce nom, modifiant ainsi 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

Si vous avez une variable locale portant le même nom, vous pouvez utiliser le globals () fonction .

globals()['your_global_var'] = 42

Par la suite et en tant que complément, utilisez un fichier pour contenir toutes les variables globales, toutes déclarées localement, puis importez en tant que :

Fichier initval.py :

Stocksin = 300
Prices = []

Fichier getstocks.py :

import initval as iv

def getmystocks(): 
    iv.Stocksin = getstockcount()


def getmycharts():
    for ic in range(iv.Stocksin):

L'écriture dans des éléments explicites d'un tableau global n'a apparemment pas besoin de la déclaration globale, bien que vous y écriviez "en 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

Référencez l'espace de nom de classe où vous souhaitez que les modifications apparaissent.

Dans cet exemple, le coureur utilise max à partir du fichier config. Je souhaite que mon test modifie la valeur de max lorsque le coureur 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 pas vu dans aucune des autres réponses et cela pourrait être utile pour quelqu'un qui lutte avec quelque chose de similaire. La fonction globals () renvoie une variable globale mutable. dictionnaire de symboles 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 vider / charger des variables de et dans l'espace de noms global Super pratique, pas de muss, pas de chichi. Je suis sûr que ce n’est que Python 3.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top