2011-07-27 15 views
15

Aktualnie uczę się Pythona i muszę pracować nad projektem Python 2.7.dostęp do "zakresu modułów" vars

Uzyskiwanie dostępu do zmiennych "zakresu modułów" w funkcjach samego modułu jest dla mnie nieco dezorientujące i nie udało mi się znaleźć satysfakcjonującego sposobu.

Moje próby do tej pory:

Way 1:

my_module.py

my_global_var = None 

def my_func(): 
    global my_global_var 
    my_global_var = 'something_else' 

Tutaj myślę, że mylące lokalne i "Zakres" Vars moduł może być całkiem proste.

Way 2:

my_module.py

import my_module 

my_global_var = None 

def my_func(): 
    my_module.my_global_var = 'something_else' 

Tutaj nazwa "my_module" może nie być tak łatwo zmienić w "drodze 1" w razie potrzeby. Dodatkowo, import modułu do samego siebie brzmi dość dziwnie.

Co byś polecił? A może zaproponowałbyś coś innego? Dzięki.

+1

Nie używaj '2' Way, Way używać' 1 '. Python, zakres i zadania są interesujące. Podczas odczytywania wartości z nazwiska tłumacz będzie zawsze wyszukiwał nazwę z najbardziej wewnętrznego zakresu na zewnątrz. Kiedy przypisujesz wartość do nazwy, robi to w bieżącym zakresie.Oznacza to, że jeśli przypiszesz do 'my_global_var' bez słowa kluczowego' global', twój moduł będzie miał dwa różne 'my_global_var' od punktu zagnieżdżonego przypisania zakresu i poza nim w zakresie zagnieżdżonym. Oświadczenie globalne mówi po prostu interpreterowi o przypisaniu wartości do zakresu 'global' dla nazwy' my_global_var'. – Matt

Odpowiedz

19

Prawdopodobnie chcesz przeczytać na Python's namespaces. Sposób 1 jest poprawna, ale generalnie niepotrzebny, nigdy nie używać 2. łatwiejsze podejście jest po prostu użyć dict (lub klasy lub innego obiektu):

my_globals = {'var': None} 

def my_func(): 
    my_globals['var'] = 'something else' 

Zadania zawsze iść do zakresu najgłębszej i zakres najgłębsza jest zawsze najpierw wyszukiwane, a więc potrzeba globalnego słowa kluczowego. W tym przypadku nie przypisujesz nazwy, więc nie jest to konieczne.

+3

Ah. Wartości dyktowane mogą być modyfikowane w zakresie funkcji, ale nie w wartościach nieprzetworzonych. Python wydaje się tu dość sprzeczny z intuicją. W każdym razie to działa i pasuje dokładnie do mojej potrzeby. dzięki –

+0

Przydziały zawsze idą w najgłębszy zakres i zawsze są najpierw wyszukiwane, a więc potrzeba słowa kluczowego "global". W tym przypadku nie przypisujesz nazwy, więc jest to niepotrzebne (Python przeszuka najskrytszy zakres, a znalezienie "my_globals" w końcu nie osiągnie zasięgu na poziomie modułu.) – zeekay

+0

Dzięki za szczegółowe wyjaśnienia dotyczące tego zachowania. Rozumiem lepiej. –

3

Sposób 1 to poprawny sposób, gdy absolutnie musi ponownie powiązać zmienną globalną. Jednak powinieneś zadać sobie pytanie, dlaczego modyfikujesz globalnie i czy jest coś lepszego, co możesz zrobić (na przykład hermetyzacja zachowania w klasie).

Należy unikać importowania modułu do samego siebie, ponieważ jest on podatny na błędy. Jeśli moduł jest także skryptem, czasami trzeba zaimportować __main__, lub jeśli moduł jest częścią pakietu, być może powinieneś importować foo.my_module. Krótko mówiąc, nie rób tego.

1

Unikaj ustawiania globali w ogóle. Możesz tworzyć nowe przestrzenie nazw z klasami dość łatwo, więc używaj zmiennych klas, jeśli musisz.

Dla każdego poważnego potrzebujesz odpowiedniego projektu z klasami.

+1

Dzięki za odpowiedź. Chciałbym stworzyć singleton, a zalecany sposób wydaje się po prostu tworzyć moduł (zobacz http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons- w-python), więc wolałbym unikać zajęć w tym konkretnym przypadku. –

+0

@FrostyZ - Odradzam używanie modułu jako singletonu, jeśli nie z innego powodu, niż to, że testowanie urządzenia jest naprawdę trudne. Zobacz

+0

Nawet do testowania, niektóre singletony wydają się akceptowalne (np. rejestrator). Zobacz http://googletesting.blogspot.com/2008/08/root-cause-of-singletons.html –

3

Importowanie modułu do samego siebie może mieć niepożądane efekty uboczne (np. Sprawdzanie wyciągów więcej niż jeden raz.) Proponuję użyć "Way 1" i narzędzia takiego jak pylint, aby pomóc zweryfikować kod i wymusić powszechne praktyki.

pylint można znaleźć na stronie: http://www.logilab.org/project/pylint

Powiązane problemy