2011-01-07 14 views
10

Sto utilizzando una lista in cui alcune funzioni funzionano nel mio programma. Questa è una lista condivisa e tutte le mie funzioni possono modificarla. È davvero necessario definirlo come "globale" in tutte le funzioni?Definizione di elenchi come variabili globali in Python

Voglio dire mettere la parola chiave globale dietro di esso in ogni funzione che lo utilizza, o definirlo al di fuori di tutte le funzioni è sufficiente senza utilizzare la parola globale dietro la sua definizione?

+5

Naturalmente non sapere che le variabili globali sono eeeevil? Quando possibile, non scrivere funzioni che dipendono da qualcosa di diverso dagli argomenti. E mai, a meno che in circostanze molto rare, modifichi qualcosa di globale da più di un punto. Non è quasi mai necessario ed è incline ad aggiungere enormi mal di testa in seguito. In conclusione, non ne vale la pena. – delnan

risposta

22

Quando si assegna una variabile (x = ...), si crea una variabile nell'ambito corrente (ad esempio locale alla funzione corrente). Se capita di ombreggiare una variabile da un ambito esterno (ad esempio globale), troppo male - a Python non importa (e questa è una buona cosa). Quindi non puoi fare questo:

x = 0 
def f(): 
    x = 1 
f() 
print x #=>0 

e aspettare 1. Invece, è necessario fare dichiarare che si intende utilizzare il global x:

x = 0 
def f(): 
    global x 
    x = 1 
f() 
print x #=>1 

Ma nota che l'assegnazione di una variabile è molto diverso da chiamate di metodo. Puoi sempre chiamare i metodi su qualsiasi cosa nell'ambito - ad es. su variabili che provengono da un ambito esterno (ad esempio globale) perché nulla di locale le ombreggia.

anche molto importante: l'assegnazione Stati (x.name = ...), assegnazione item (collection[key] = ...), assegnamento di una fetta (sliceable[start:end] = ...) e riordinata più sono tutti metodo di chiamate, come pure! E quindi non hai bisogno di global per cambiare i membri di un globale o chiamarlo metodi (anche quando mutano l'oggetto).

+4

+1. Vale anche la pena notare che le assegnazioni di sezioni non sovrascriveranno il riferimento. In particolare, invece di 'x = newlist', si può fare' x [:] = new_list' e non si ha ancora bisogno di usare 'global'. Questo è ovviamente coperto dal caso d'uso del metodo, ma vale la pena indicarlo esplicitamente. – aaronasterling

+0

@aaron: Sì. Espanso per chiarire che ci sono molte cose (tra cui l'assegnazione dei membri, l'assegnazione delle fette, ecc.) Sono in realtà chiamate ai metodi. – delnan

4

Sì, è necessario utilizzare global foo se si sta per scrivere ad esso.

foo = [] 

def bar(): 
    global foo 
    ... 
    foo = [1] 
+1

Anche se non è completamente sbagliato (nell'esempio, 'global 'è necessario), questo è fuorviante. Per cominciare, molti sembrano non essere d'accordo con la nozione di Python di quando "scrivi". – delnan

+0

grazie, è anche questo il caso dei dizionari? – Hossein

+2

@Hossein: è lo stesso per qualsiasi variabile. L'oggetto a cui si fa riferimento non ha importanza. – delnan

1

No, è possibile specificare l'elenco come argomento della parola chiave per la propria funzione.

alist = [] 
def fn(alist=alist): 
    alist.append(1) 
fn() 
print alist # [1] 

Direi che è una cattiva pratica. Tipo di troppo hackerato. Se hai davvero bisogno di usare una struttura di dati a livello di singolo standard globalmente, userei l'approccio a livello di modulo variabile, ovvero metti 'alist' in un modulo e poi negli altri tuoi moduli importa questa variabile:

In file foomodule.py:

alist = [] 

Nel file di barmodule.py:

import foomodule 
def fn(): 
    foomodule.alist.append(1) 
print foomodule.alist # [1] 
+0

Chiarimento: "Globali" sono * sempre * a livello di modulo. Non c'è bisogno di metterlo in un modulo aggiuntivo (a volte utile o semanticamente più corretto però). – delnan

+0

Non ero a conoscenza delle complessità implicate. Sembra che i due esempi che ho scritto non siano affatto necessari se tutto ciò che si vuole fare è modificare una variabile di livello del modulo (cioè, non fare un assegnamento al nome globale). Vedi la risposta di delnan per una valutazione molto migliore. – XORcist