Domanda Utilizzo di variabili globali in una funzione


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

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


2466
2018-01-08 05:45


origine


risposte:


Puoi usare una variabile globale in altre funzioni dichiarandola come global in ogni funzione che assegna ad esso:

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 per cui è che, dal momento che le variabili globali sono così pericolose, Python vuole assicurarsi che tu sappia davvero che è quello con cui stai giocando richiedendo esplicitamente global parola chiave.

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


3495
2018-01-08 08:39



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

Di 'che hai un modulo come questo:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Potresti aspettarti che questo stampi 42, ma invece stampa 5. Come è già stato detto, se aggiungi un 'global'dichiarazione a func1(), poi func2() stamperà 42.

def func1():
    global myGlobal
    myGlobal = 42

Quello che sta succedendo qui è che Python presuppone che qualsiasi nome sia assegnato a, ovunque all'interno di una funzione, è locale rispetto a quella funzione se non diversamente specificato. Se è solo lettura 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 myGlobalquindi, Python crea una variabile locale che ombreggia la variabile globale con lo stesso nome. Quel locale va fuori portata ed è garbage collection quando func1() ritorna; Nel frattempo, func2() non può mai vedere nient'altro che il nome globale (non modificato). Si noti che questa decisione dello spazio dei nomi avviene in fase di compilazione, non in fase di runtime, se si dovesse leggere il valore di myGlobal dentro func1() prima di assegnarlo, otterresti un UnboundLocalError, perché Python ha già deciso che deve essere una variabile locale ma non ha ancora avuto alcun valore associato. Ma usando il 'global'affermazione, dite a Python che dovrebbe cercare altrove il nome invece di assegnarlo localmente.

(Credo che questo comportamento sia nato principalmente dall'ottimizzazione dei namespace locali - senza questo comportamento, la VM di Python avrebbe bisogno di eseguire almeno tre ricerche di nomi ogni volta che un nuovo nome viene assegnato all'interno di una funzione (per assicurarsi che il nome non abbia esiste già a livello di modulo / incorporato), il che rallenterebbe in modo significativo un'operazione molto comune).


660
2018-01-08 09:19



Potresti voler esplorare la nozione di spazi dei nomi. In Python, il modulo è il posto naturale per globale dati:

Ogni modulo ha la 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 variabili globali nel modulo senza preoccuparsi di conflitti 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 riferirsi alle sue funzioni, modname.itemname.

Qui è descritto un uso specifico di global-in-a-module - how-do-i-share-global-variabili-tutta-modulese per completezza i contenuti sono condivisi qui:

Il modo canonico di condividere le informazioni tra i moduli all'interno di un singolo programma consiste nel creare un modulo di configurazione speciale (spesso chiamato config o cfg). Importa semplicemente il modulo di configurazione in tutti i moduli della tua applicazione; il modulo diventa quindi disponibile come nome globale. Poiché esiste una sola istanza di ciascun modulo, qualsiasi modifica apportata all'oggetto modulo viene riflessa ovunque. Per 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

175
2018-01-08 05:59



Python usa una semplice euristica per decidere quale ambito deve caricare una variabile da, tra locale e globale. Se il nome di una variabile appare sul lato sinistro di un compito, ma non è dichiarato globale, si presume che sia locale. Se non appare 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 incarico in foo(), è l'unico LOAD_FAST variabile.


75
2017-07-12 12:35



Se si desidera fare riferimento a una variabile globale in una funzione, è possibile utilizzare il globale parola chiave per dichiarare quali variabili sono globali. Non è necessario utilizzarlo in tutti i casi (come affermato da qualcuno qui in modo errato) - se non è possibile trovare il nome referenziato in un'espressione in ambito locale o ambiti nelle funzioni in cui è definita questa funzione, viene cercato tra gli indirizzi globali 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, al contrario di alcuni zeloti OOP che affermano il contrario - specialmente per gli script più piccoli, in cui l'OOP è eccessivo.


47
2018-01-08 09:03



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

In Python, le variabili che sono solo referenziate all'interno di una funzione sono    implicitamente globale. Se a una variabile viene assegnato un nuovo valore ovunque   all'interno del corpo della funzione, si presume che sia a Locale. Se una variabile   è mai stato assegnato un nuovo valore all'interno della funzione, la variabile è   implicitamente locale, e devi dichiararlo esplicitamente come "globale".

Anche se un po 'sorprendente all'inizio, un momento di riflessione spiega   Questo. Da una parte, 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, staresti utilizzando tutto il mondo   tempo. Dovresti dichiarare come globale ogni riferimento a un built-in   funzione o a 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?.


36
2017-07-04 10:23



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' 

Scrivere una funzione in realtà non esegue il suo codice. Quindi chiamiamo il create_global_variable funzione:

>>> create_global_variable()

Utilizzo di globals senza modifiche

Puoi semplicemente usarlo, a patto che non ti aspetti di cambiare l'oggetto a cui punta:

Per 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 lo ha effettivamente modificato non è ancora stato eseguito:

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

Quindi dopo aver chiamato la funzione:

>>> change_global_variable()

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

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

Nota che "globale" in Python non è veramente globale - è solo globale rispetto al livello del 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:

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

Ma usare quella variabile locale erroneamente detta non cambia la variabile globale:

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

Nota che dovresti evitare di usare le variabili locali con lo stesso nome dei globali a meno che tu non sappia esattamente cosa stai facendo e abbia una buona ragione per farlo. Non ho ancora incontrato una tale ragione.


31
2018-01-01 19:55