Jaki jest zakres zmiennej inicjalizowanej w instrukcji if?

Jestem nowy w Pythonie, więc jest to prawdopodobnie proste pytanie dotyczące zakresu. Poniższy kod w pliku (module) Pythona nieco mnie myli:

if __name__ == '__main__':
    x = 1

print x

W innych językach, w których pracowałem, ten kod rzuciłby wyjątek, ponieważ zmienna x jest lokalna dla instrukcji if i nie powinna istnieć poza nią. Ale ten kod wykonuje i wypisuje 1. Czy ktoś może wyjaśnić to zachowanie? Czy wszystkie zmienne utworzone w module są globalne/dostępne dla całego modułu?

Author: nbro, 2010-05-13

8 answers

Zmienne Pythona są przypisane do najbardziej wewnętrznej funkcji, klasy lub modułu, do którego są przypisane. Bloki kontrolne, takie jak if i while nie liczą się, więc zmienna przypisana wewnątrz if jest nadal przypisana do funkcji, klasy lub modułu.

(Funkcje niejawne zdefiniowane przez wyrażenie generatora lub listę / zbiór / słownik liczą się, podobnie jak wyrażenia lambda. W żadnym z nich nie można wgrać instrukcji assignment, ale parametry lambda i cele klauzuli {[3] } są niejawnym zadaniem.)

 341
Author: Luke Maurer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-22 17:26:14

Tak, są w tym samym "zasięgu lokalnym", a tak naprawdę kod taki jest powszechny w Pythonie:

if condition:
  x = 'something'
else:
  x = 'something else'

use(x)

Zauważ, że x nie jest zadeklarowana ani zainicjalizowana przed warunkiem, tak jak na przykład w C lub Javie.

Innymi słowy, Python nie ma zakresów na poziomie bloków. Bądź jednak ostrożny z przykładami takimi jak

if False:
    x = 3
print(x)

Co wyraźnie wywołałoby NameError wyjątek.

 121
Author: Eli Bendersky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-22 17:02:48

Zakres w Pythonie podąża za tą kolejnością:

  • Szukaj zakresu lokalnego

  • Przeszukiwanie zakresu dowolnych funkcji

  • Przeszukaj globalny zakres

  • Szukaj wbudowanych

(Źródło)

Zauważ, że if i inne konstrukcje pętlujące / rozgałęziające nie są wymienione - tylko klasy, funkcje i moduły zapewniają zakres w Pythonie, więc wszystko zadeklarowane w bloku if ma taki sam zakres jak cokolwiek / align = "left" / Zmienne nie są sprawdzane podczas kompilacji, dlatego inne języki rzucają wyjątek. W Pythonie, tak długo, jak zmienna istnieje w czasie, gdy jej potrzebujesz, żaden wyjątek nie zostanie wyrzucony.

 45
Author: Daniel G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-13 19:13:14

W przeciwieństwie do języków takich jak C, zmienna Pythona jest w zasięgu całej funkcji (lub klasy lub modułu), w której się pojawia, a nie tylko w najgłębszym "bloku". To tak, jakbyś zadeklarował int x u góry funkcji (lub klasy lub modułu), z tym wyjątkiem, że w Pythonie nie musisz deklarować zmiennych.

Zauważ, że istnienie zmiennej x jest sprawdzane tylko w czasie wykonywania-to znaczy, gdy przejdziesz do instrukcji print x. If __name__ didn ' t equal "__main__" then you would get an wyjątek: NameError: name 'x' is not defined.

 12
Author: Paul Stephenson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-13 19:33:40

Jak powiedział Eli, Python nie wymaga deklaracji zmiennych. W C można by powiedzieć:

int x;
if(something)
    x = 1;
else
    x = 2;

Ale w Pythonie deklaracja jest niejawna, więc po przypisaniu do x jest automatycznie deklarowana. To dlatego, że Python jest pisany dynamicznie - to nie działa w języku statycznie pisanym, ponieważ w zależności od użytej ścieżki, zmienna może być używana bez deklaracji. To zostałoby przechwycone w czasie kompilacji w języku statycznie wpisywanym, ale w języku dynamicznie wpisywanym jest dozwolone.

Jedynym powodem, dla którego statycznie typowany język jest ograniczony do konieczności deklarowania zmiennych poza poleceniami if z powodu tego problemu. Embrace the dynamic!

 11
Author: Skilldrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-13 19:20:27

Tak. Dotyczy to również zakresu for. Ale oczywiście nie działa.

W twoim przykładzie: jeśli warunek w instrukcji if jest fałszywy, x nie zostanie jednak zdefiniowany.

 4
Author: Olivier Verdier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-13 19:10:31

Wykonujesz ten kod z linii poleceń, dlatego if conditions jest true i x jest ustawione. Porównaj:

>>> if False:
    y = 42


>>> y
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    y
NameError: name 'y' is not defined
 2
Author: SilentGhost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-13 19:10:56

I zauważ, że ponieważ typy Pythona są sprawdzane tylko w czasie wykonywania, możesz mieć kod w stylu:

if True:
    x = 2
    y = 4
else:
    x = "One"
    y = "Two"
print(x + y)

Ale mam problem z myśleniem o innych sposobach działania kodu bez błędu z powodu problemów z typem.

 0
Author: cowang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-27 16:49:07