2011-01-07 12 views
10

Używam listy, na której niektóre funkcje działają w moim programie. To jest faktycznie udostępniona lista i wszystkie moje funkcje mogą ją edytować. Czy naprawdę konieczne jest zdefiniowanie go jako "globalnego" we wszystkich funkcjach?Definiowanie list jako zmiennych globalnych w Pythonie

Mam na myśli umieszczenie globalnego słowa kluczowego za nim w każdej funkcji, która go używa, lub zdefiniowanie go poza wszystkimi funkcjami wystarczy bez użycia globalnego słowa kryjącego się za jego definicją?

+5

oczywiście, że wiem, że zmienne globalne są eeeevil? Jeśli to możliwe, nie pisz funkcji zależnej od niczego innego niż argumenty. I nigdy, chyba że w bardzo rzadkich okolicznościach, modyfikować coś globalnego z więcej niż jednego punktu. To prawie nigdy nie jest konieczne i jest skłonne do późniejszego dodawania ogromnych bólów głowy. Podsumowując, nie warto. – delnan

Odpowiedz

22

Po przypisaniu zmiennej (x = ...), tworzysz zmienną w bieżącym zakresie (na przykład lokalny do bieżącej funkcji). Jeśli dzieje się z cieniem zmienną przed zewnętrznym (np. Globalnym) zasięgiem, to o wiele za dobrze - Python nie dba o to (i to dobrze). Więc nie można tego zrobić:

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

i oczekują 1. Zamiast tego trzeba deklaruje, że zamierza korzystać z global x:

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

Należy jednak pamiętać, że przypisanie zmiennej jest bardzo różni się od wywołań metod. Zawsze możesz wywoływać metody w dowolnych zakresach - np. na zmiennych, które pochodzą z zewnętrznego (np. globalnego) zakresu, ponieważ nic lokalnego nie powoduje ich cieniowania.

także bardzo ważne: przypisanie państw (x.name = ...), przypisanie pozycji (collection[key] = ...), cesja slice (sliceable[start:end] = ...) i propably bardziej są metoda nazywa, jak dobrze! I dlatego nie potrzebujesz global, aby zmienić członków globalnych lub nazwać ich metodami (nawet gdy mutują obiekt).

+4

+1. Warto również zauważyć, że przypisania plasterków nie zastąpią odniesienia. W szczególności, zamiast 'x = newlist', można zrobić' x [:] = new_list' i nadal nie ma potrzeby używania 'global'. Jest to oczywiście objęte przypadkiem wywołania metody, ale warto to wyraźnie wskazać. – aaronasterling

+0

@aaron: Tak. Rozwinięty, aby wyjaśnić, że istnieje wiele rzeczy (w tym przypisanie członków, przypisanie plasterków, itp.) Są w rzeczywistości wywołaniami metod. – delnan

4

Tak, musisz wpisać global foo, jeśli zamierzasz do niego pisać.

foo = [] 

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

Chociaż nie jest to absolutnie błędne (w tym przykładzie konieczne jest 'globalne'), jest to mylące. Na początek wielu nie zgadza się z pytaniem Pythona, kiedy "piszesz do niego". – delnan

+0

dziękuję, czy tak jest również w przypadku słowników? – Hossein

+2

@Hossein: To jest to samo dla każdej zmiennej. Obiekt, do którego się odwołuje, nie ma znaczenia. – delnan

1

Nie, możesz określić listę jako argument słowa kluczowego dla swojej funkcji.

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

Powiedziałbym, że to zła praktyka. Trochę zbyt hackish. Jeśli naprawdę potrzebujesz użyć globalnie dostępnej struktury danych typu singleton, użyłbym metody zmiennej poziomu modułów, tj. wstaw "alist" w module, a następnie w innych modułach zaimportuj tę zmienną:

W pliku foomodule.py:

alist = [] 

W pliku barmodule.py:

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

Wyjaśnienie: "Globals" to * zawsze * poziom modułów. Nie ma potrzeby umieszczania go w dodatkowym module (czasem przydatnym lub semantycznie bardziej poprawnym). – delnan

+0

Nie byłem świadomy zawiłości. Wydaje się, że dwa przykłady, które napisałem, nie są wcale potrzebne, jeśli wszystko, co chcesz zrobić, to zmodyfikować zmienną poziomu modułu (to znaczy nie przypisywać nazwy globalnej). Zobacz odpowiedź delnana na znacznie lepszą ocenę. – XORcist

Powiązane problemy