Zakresy w pętlach Pythona "dla"

Nie pytam o zasady scopowania Pythona; ogólnie Rozumiem Jak scopowanie działa w Pythonie dla pętli. Moje pytanie brzmi Dlaczego decyzje projektowe zostały podjęte w ten sposób. Na przykład (nie zamierzony kalambur):

for foo in xrange(10):
    bar = 2
print(foo, bar)

Powyższa zostanie wydrukowana (9,2).

Wydaje mi się to dziwne: 'foo' jest tak naprawdę tylko kontrolowaniem pętli, a 'bar' został zdefiniowany wewnątrz pętli. Rozumiem, dlaczego może być konieczne, aby " bar " był dostępny poza pętlą (w przeciwnym razie pętle for mają bardzo ograniczoną funkcjonalność). Nie rozumiem, dlaczego zmienna sterująca musi pozostać w zasięgu po wyjściu pętli. Z mojego doświadczenia wynika, że po prostu zaśmieca to globalną przestrzeń nazw i utrudnia wytropienie błędów, które mogłyby zostać wykryte przez tłumaczy w innych językach.

 189
Author: chimeracoder, 2010-08-31

6 answers

Najbardziej prawdopodobną odpowiedzią jest to, że po prostu zachowuje prostą gramatykę, nie jest przeszkodą do przyjęcia i wielu z nich było zadowolonych, że nie trzeba disambiguate zakresu, do którego należy nazwa podczas przypisywania do niej w konstrukcji pętli. Zmienne nie są deklarowane w ramach zakresu, wynika to z położenia instrukcji assignment. Słowo kluczowe global istnieje tylko z tego powodu (aby zaznaczyć, że przypisanie jest wykonywane na globalnym zakres).

Update

Oto dobra dyskusja na ten temat: http://mail.python.org/pipermail/python-ideas/2008-October/002109.html

Poprzednie propozycje tworzenia for-loop zmienne lokalne do pętli mają natknąłem się na problem istniejących kod, który opiera się na zmiennej pętli zachowanie jego wartości po wyjściu z pętli, i wydaje się, że jest to uważany za pożądaną cechę.

Krótko mówiąc, prawdopodobnie możesz to winić o społeczności Pythona: P

 117
Author: Jeremy Brown,
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-08-31 18:38:30

Python nie posiada bloków, podobnie jak niektóre inne języki (takie jak C / C++ czy Java). Dlatego Jednostka zasięgu w Pythonie jest funkcją.

 63
Author: atzz,
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-08-31 18:04:12

A naprawdę przydatny przypadek ponieważ jest to gdy używasz enumerate i chcesz mieć całkowitą liczbę na końcu:

for count, x in enumerate(someiterator, start=1):
    dosomething(count, x)
print "I did something {0} times".format(count)
Czy to konieczne? Nie. Ale z pewnością jest to wygodne.

Kolejna rzecz, o której należy pamiętać: w Pythonie 2, zmienne w składaniu list również są wyciekane:

>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> x
9

Ale to samo nie dotyczy Pythona 3.

 40
Author: carl,
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-11-07 16:54:01

Jeśli masz instrukcję break w pętli (i chcesz użyć później wartości iteracji, być może do pobrania z powrotem, indeksowania czegoś lub nadania statusu), zapisuje ci to jedną linię kodu i jedno przypisanie, więc jest wygoda.

 2
Author: Mac,
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
2018-09-07 15:59:38

[[0]}jednym z podstawowych wpływów Pythona jest ABC , język opracowany w Holandii do nauczania koncepcji programowania dla początkujących. Twórca Pythona, Guido van Rossum, pracował nad ABC przez kilka lat w latach 80. Nie wiem prawie nic o ABC, ale ponieważ jest przeznaczony dla początkujących, przypuszczam, że musi mieć ograniczoną liczbę zakresów, podobnie jak wczesne podstawy.

 1
Author: kindall,
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
2018-02-28 16:41:23

Na początek, gdyby zmienne były lokalne dla pętli, pętle te byłyby bezużyteczne dla większości programów w świecie rzeczywistym.

W obecnej sytuacji:

# Sum the values 0..9
total = 0
for foo in xrange(10):
    total = total + foo
print total

Daje 45. Teraz zastanów się, jak działa przypisanie w Pythonie. Jeśli zmienne pętli były ściśle lokalne:

# Sum the values 0..9?
total = 0
for foo in xrange(10):
    # Create a new integer object with value "total + foo" and bind it to a new
    # loop-local variable named "total".
    total = total + foo
print total

Daje 0, Ponieważ total wewnątrz pętli po przypisaniu nie jest tą samą zmienną, co total poza pętlą. Nie byłoby to optymalne lub oczekiwane zachowanie.

 -2
Author: Kirk Strauser,
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
2012-05-12 23:53:04