Domanda

Come posso creare o usare una variabile globale in una funzione?

Se creo una variabile globale in una funzione, come posso usare quella variabile globale in un'altra funzione? Devo memorizzare la variabile globale in una variabile locale della funzione che necessita del suo accesso?

È stato utile?

Soluzione

Puoi utilizzare una variabile globale in altre funzioni dichiarandola come global in ciascuna funzione che le assegna:

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

Immagino che la ragione sia che, dal momento che le variabili globali sono così pericolose, Python vuole assicurarsi di sapere davvero che cosa stai giocando richiedendo esplicitamente la parola chiave global .

Vedi altre risposte se vuoi condividere una variabile globale tra i moduli.

Altri suggerimenti

Se capisco correttamente la tua situazione, quello che vedi è il risultato di come Python gestisce gli spazi dei nomi locali (funzione) e globali (modulo).

Supponi di avere un modulo come questo:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Potresti aspettarti che ciò stampi 42, ma invece stampa 5. Come già accennato, se aggiungi una dichiarazione " globale " a func1 () , quindi func2 () stamperà 42.

def func1():
    global myGlobal
    myGlobal = 42

Quello che sta succedendo qui è che Python assume che qualsiasi nome assegnato a , ovunque all'interno di una funzione, sia locale a quella funzione se non diversamente specificato. Se sta solo leggendo da un nome e il nome non esiste localmente, proverà a cercare il nome in qualsiasi ambito contenente (ad esempio l'ambito globale del modulo).

Quando assegni 42 al nome myGlobal , quindi, Python crea una variabile locale che ombreggia la variabile globale con lo stesso nome. Il locale non rientra nel campo di applicazione ed è immondizia raccolta quando func1 () restituisce; nel frattempo, func2 () non può mai vedere altro che il nome globale (non modificato). Tieni presente che questa decisione dello spazio dei nomi viene eseguita al momento della compilazione, non in fase di esecuzione. Se dovessi leggere il valore di myGlobal all'interno di func1 () prima di assegnarlo, devi " d ottenere un UnboundLocalError , perché Python ha già deciso che deve essere una variabile locale ma non ha ancora associato alcun valore. Ma usando l'istruzione ' global ', dici a Python che dovrebbe cercare altrove il nome invece di assegnarlo localmente.

(Credo che questo comportamento abbia avuto origine in gran parte attraverso un'ottimizzazione degli spazi dei nomi locali - senza questo comportamento, la VM di Python dovrebbe eseguire almeno tre ricerche di nomi ogni volta che viene assegnato un nuovo nome all'interno di una funzione (per garantire che il il nome non esisteva già a livello di modulo / incorporato), il che rallenterebbe significativamente un'operazione molto comune.)

Potresti voler esplorare l'idea di namespace . In Python, il modulo è il luogo naturale per globale dati:

  

Ogni modulo ha una propria tabella dei simboli privata, che viene utilizzata come tabella dei simboli globale da tutte le funzioni definite nel modulo. Pertanto, l'autore di un modulo può utilizzare le variabili globali nel modulo senza preoccuparsi di scontri accidentali con le variabili globali di un utente. D'altra parte, se sai cosa stai facendo, puoi toccare le variabili globali di un modulo con la stessa notazione usata per fare riferimento alle sue funzioni, modname.itemname .

Qui viene descritto un uso specifico di global-in-a-module - Come posso condividere le variabili globali tra i moduli? , e per completezza i contenuti sono condivisi qui:

  

Il modo canonico di condividere informazioni tra i moduli all'interno di un singolo programma è quello di creare un modulo di configurazione speciale (spesso chiamato config o cfg ). Basta importare il modulo di configurazione in tutti i moduli dell'applicazione; il modulo diventa quindi disponibile come nome globale. Poiché esiste solo un'istanza di ciascun modulo, tutte le modifiche apportate all'oggetto modulo vengono riflesse ovunque. Ad esempio:

     

File: config.py

x = 0   # Default value of the 'x' configuration setting
     

File: mod.py

import config
config.x = 1
     

File: main.py

import config
import mod
print config.x

Python usa una semplice euristica per decidere da quale ambito dovrebbe caricare una variabile, tra locale e globale. Se un nome di variabile appare sul lato sinistro di un compito, ma non è dichiarato globale, si presume che sia locale. Se non viene visualizzato sul lato sinistro di un compito, si presume che sia globale.

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

Guarda come baz, che appare sul lato sinistro di un compito in foo () , è l'unica variabile LOAD_FAST .

Se vuoi fare riferimento a una variabile globale in una funzione, puoi usare la parola chiave globale per dichiarare quali variabili sono globali. Non è necessario utilizzarlo in tutti i casi (come afferma erroneamente qualcuno qui) - se il nome a cui viene fatto riferimento in un'espressione non può essere trovato in ambito locale o ambiti nelle funzioni in cui questa funzione è definita, viene cercata tra globale variabili.

Tuttavia, se si assegna a una nuova variabile non dichiarata come globale nella funzione, viene implicitamente dichiarata come locale e può oscurare qualsiasi variabile globale esistente con lo stesso nome.

Inoltre, le variabili globali sono utili, contrariamente ad alcuni fanatici di OOP che sostengono diversamente, specialmente per script più piccoli, dove OOP è eccessivo.

Oltre alle risposte già esistenti e per renderlo più confuso:

  

In Python lo sono solo le variabili a cui si fa riferimento all'interno di una funzione    implicitamente globale . Se a una variabile viene assegnato un nuovo valore ovunque   all'interno del corpo della funzione, si presume che sia un locale . Se una variabile   viene mai assegnato un nuovo valore all'interno della funzione, la variabile è   implicitamente locale e devi dichiararlo esplicitamente come & # 8216; global & # 8217 ;.

     

Sebbene all'inizio sia un po 'sorprendente, una considerazione del momento spiega   Questo. Da un lato, la richiesta globale per le variabili assegnate fornisce a   barra contro effetti collaterali indesiderati. D'altra parte, se fosse globale   richiesto per tutti i riferimenti globali, dovresti utilizzare globale tutto il   tempo. Dovresti dichiarare come globale ogni riferimento a un built-in   o ad un componente di un modulo importato. Questo disordine sarebbe   sconfiggere l'utilità della dichiarazione globale per l'identificazione   effetti collaterali.

Fonte: Quali sono le regole per le variabili locali e globali in Python? .

  

Se creo una variabile globale in una funzione, come posso usare quella variabile in un'altra funzione?

Possiamo creare un globale con la seguente funzione:

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' 

La scrittura di una funzione non esegue effettivamente il suo codice. Quindi chiamiamo la funzione create_global_variable :

>>> create_global_variable()

Uso dei globali senza modifiche

Puoi semplicemente usarlo, purché non preveda di cambiare l'oggetto a cui punta:

Ad esempio,

def use_global_variable():
    return global_variable + '!!!'

e ora possiamo usare la variabile globale:

>>> use_global_variable()
'Foo!!!'

Modifica della variabile globale dall'interno di una funzione

Per puntare la variabile globale su un oggetto diverso, è necessario utilizzare nuovamente la parola chiave globale:

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

Nota che dopo aver scritto questa funzione, il codice che la modifica effettivamente non è ancora stato eseguito:

>>> change_global_variable()

Quindi dopo aver chiamato la funzione:

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

possiamo vedere che la variabile globale è stata cambiata. Il nome global_variable ora punta a 'Bar' :

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

Nota che " globale " in Python non è veramente globale, è solo globale a livello di modulo. Quindi è disponibile solo per le funzioni scritte nei moduli in cui è globale. Le funzioni ricordano il modulo in cui sono scritte, quindi quando vengono esportate in altri moduli, continuano a cercare nel modulo in cui sono state create per trovare le variabili globali.

Variabili locali con lo stesso nome

Se crei una variabile locale con lo stesso nome, oscurerà una variabile globale:

<*>

Ma l'uso di quella variabile locale erroneamente non cambia la variabile globale:

<*>

Nota che dovresti evitare di usare le variabili locali con gli stessi nomi dei globali se non sai esattamente cosa stai facendo e hai un'ottima ragione per farlo. Non ho ancora riscontrato un motivo del genere.

Con l'esecuzione parallela, le variabili globali possono causare risultati imprevisti se non capisci cosa sta succedendo. Ecco un esempio dell'uso di una variabile globale all'interno del multiprocessing. Possiamo vedere chiaramente che ogni processo funziona con la propria copia della variabile:

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))

Output:

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]

A quanto pare la risposta è sempre semplice.

Ecco un piccolo modulo di esempio con un modo semplice per mostrarlo in una definizione main :

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

def isTheNumber():
    return helper

Ecco come mostrarlo in una definizione main :

import TestPy

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

if __name__ == '__main__':
    main()

Questo semplice codice funziona così e verrà eseguito. Spero che sia d'aiuto.

Quello che stai dicendo è usare il metodo in questo modo:

globvar = 5

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

f()  # Prints 5

Ma il modo migliore è usare la variabile globale in questo modo:

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

Entrambi danno lo stesso output.

Devi fare riferimento alla variabile globale in ogni funzione che vuoi usare.

Come segue:

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]
"""

In realtà non stai memorizzando il globale in una variabile locale, stai solo creando un riferimento locale allo stesso oggetto a cui fa riferimento il tuo riferimento globale originale. Ricorda che praticamente tutto in Python è un nome che si riferisce a un oggetto, e nulla viene copiato durante le normali operazioni.

Se non dovessi specificare esplicitamente quando un identificatore si riferisse a un globale predefinito, allora dovresti presumibilmente specificare esplicitamente quando un identificatore è una nuova variabile locale (ad esempio, con qualcosa come " var 'comando visto in JavaScript). Poiché le variabili locali sono più comuni delle variabili globali in qualsiasi sistema serio e non banale, il sistema di Python ha più senso nella maggior parte dei casi.

potresti avere una lingua che ha tentato di indovinare, usando una variabile globale se esisteva o creando una variabile locale se non lo fosse. Tuttavia, sarebbe molto soggetto a errori. Ad esempio, l'importazione di un altro modulo potrebbe inavvertitamente introdurre una variabile globale con quel nome, modificando il comportamento del tuo programma.

Prova questo:

def x1():
    global x
    x = 6

def x2():
    global x
    x = x+1
    print x

x = 5
x1()
x2()  # output --> 7

Nel caso in cui tu abbia una variabile locale con lo stesso nome, potresti voler usare globals () function .

globals()['your_global_var'] = 42

Seguendo e come componente aggiuntivo, usa un file per contenere tutte le variabili globali tutte dichiarate localmente e quindi importa come :

File initval.py :

Stocksin = 300
Prices = []

File getstocks.py :

import initval as iv

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


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

Apparentemente la scrittura su elementi espliciti di un array globale non ha bisogno della dichiarazione globale, sebbene scrivergli "all'ingrosso" ha questo requisito:

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

Fai riferimento allo spazio dei nomi della classe in cui desideri visualizzare la modifica.

In questo esempio, runner sta usando max dalla configurazione del file. Voglio che il mio test cambi il valore di max quando il corridore lo sta usando.

principale / config.py

max = 15000

principale / runner.py

from main import config
def check_threads():
    return max < thread_count 

test / 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()

Lo sto aggiungendo perché non l'ho visto in nessuna delle altre risposte e potrebbe essere utile per qualcuno alle prese con qualcosa di simile. La funzione globals () restituisce un globale mutabile dizionario dei simboli in cui puoi " magicamente " rendere disponibili i dati per il resto del codice. Ad esempio:

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

e

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

Ti consentirà semplicemente di scaricare / caricare variabili da e nello spazio dei nomi globale. Super conveniente, senza complicazioni, senza complicazioni. Abbastanza sicuro è solo Python 3.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top