Jestem nowy w Pythonie, więc jest to prawdopodobnie proste pytanie dotyczące zakresu. Poniższy kod w pliku (module) Pythona nieco mnie dezorientuje:
if __name__ == '__main__':
x = 1
print x
W innych językach, w których pracowałem, ten kod zgłosiłby wyjątek, ponieważ x
zmienna jest lokalna dla if
instrukcji i nie powinna istnieć poza nią. Ale ten kod wykonuje i drukuje 1. Czy ktoś może wyjaśnić to zachowanie? Czy wszystkie zmienne są tworzone w module globalnym / dostępne dla całego modułu?
if
powyższa instrukcja nie jest prawdziwa (tzn. Nie__name__
jest , na przykład podczas importowania modułu zamiast wykonywania go na najwyższym poziomie), to nigdy nie zostanie powiązany, a kolejna instrukcja rzuci .'__main__'
x
print x
NameError: name 'x' is not defined
Odpowiedzi:
Zmienne w języku Python obejmują najbardziej wewnętrzną funkcję, klasę lub moduł, do którego są przypisane. Bloki kontrolne, takie jak
if
iwhile
bloki, nie liczą się, więc zmienna przypisana w obrębieif
jest nadal objęta funkcją, klasą lub modułem.(Funkcje niejawne zdefiniowane przez wyrażenie generatora lub rozumienie list / set / dict są liczone, podobnie jak wyrażenia lambda. Nie można wstawić instrukcji przypisania do żadnego z nich, ale parametry lambda i
for
cele klauzuli są domyślnie przypisane.)źródło
Tak, są w tym samym „zasięgu lokalnym” i tak naprawdę taki kod jest powszechny w Pythonie:
Zauważ, że
x
nie jest zadeklarowany ani zainicjowany przed warunkiem, tak jak na przykład w C lub Java.Innymi słowy, Python nie ma zasięgów na poziomie bloku. Uważaj jednak na przykłady takie jak
co wyraźnie podniosłoby
NameError
wyjątek.źródło
Zakres w python ma następującą kolejność:
Wyszukaj zasięg lokalny
Przeszukaj zakres dowolnych funkcji obejmujących
Wyszukaj zasięg globalny
Wyszukaj wbudowane
( źródło )
Zauważ, że
if
i inne konstrukcje pętli / rozgałęzień nie są wymienione - tylko klasy, funkcje i moduły zapewniają zakres w Pythonie, więc wszystko zadeklarowane wif
bloku ma taki sam zasięg jak wszystko, co zostało zadeklarowane poza tym blokiem. Zmienne nie są sprawdzane podczas kompilacji, dlatego inne języki zgłaszają wyjątek. W Pythonie, dopóki zmienna istnieje w wymaganym momencie, żaden wyjątek nie zostanie zgłoszony.źródło
Jak powiedział Eli, Python nie wymaga deklaracji zmiennej. W C powiedziałbyś:
ale w Pythonie deklaracja jest niejawna, więc po przypisaniu do x jest automatycznie deklarowana. Jest tak, ponieważ Python jest dynamicznie wpisywany - nie działałby w języku o typie statycznym, ponieważ w zależności od użytej ścieżki zmienna może być używana bez deklaracji. Zostałoby to wychwycone podczas kompilacji w języku o typie statycznym, ale w języku o typie dynamicznym jest to dozwolone.
Jedyny powód, dla którego język o typie statycznym ogranicza się do konieczności deklarowania zmiennych poza
if
instrukcjami z powodu tego problemu. Uwzględnij dynamikę!źródło
W przeciwieństwie do języków takich jak C, zmienna Pythona jest objęta zakresem całej funkcji (lub klasy lub modułu), w której się pojawia, a nie tylko w najbardziej „wewnętrznym” bloku. To tak, jakbyś zadeklarował
int x
na górze funkcji (lub klasy, lub modułu), tyle że w Pythonie nie musisz deklarować zmiennych.Zauważ, że istnienie zmiennej
x
jest sprawdzane tylko w czasie wykonywania - to znaczy po przejściu doprint x
instrukcji. Jeśli__name__
nie są równe"__main__"
wtedy można uzyskać wyjątek:NameError: name 'x' is not defined
.źródło
Tak. Dotyczy to również
for
zakresu. Ale oczywiście nie działa.W twoim przykładzie: jeśli warunek w
if
instrukcji jest fałszywy,x
nie zostanie zdefiniowany.źródło
wykonujesz ten kod z wiersza poleceń, dlatego
if
warunki są spełnione ix
ustawione. Porównać:źródło
I zauważ, że ponieważ typy Pythona są sprawdzane tylko w czasie wykonywania, możesz mieć kod taki jak:
Ale mam problem z myśleniem o innych sposobach działania kodu bez błędu z powodu problemów z typem.
źródło