Определение области в циклах Python for for

Я не спрашиваю о правилах определения Python; Я вообще понимаю, как работает область действия в Python для циклов. Мой вопрос в том, почему проектные решения были приняты таким образом. Например (без каламбура):

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

Вышеприведенное будет напечатано (9,2).

Это выглядит как странно: "foo" на самом деле просто контролирует цикл, а "bar" определен внутри цикла. Я могу понять, почему может быть необходимо, чтобы "бар" был доступен вне цикла (в противном случае для циклов была бы очень ограниченная функциональность). Я не понимаю, почему необходимо, чтобы переменная управления оставалась в области действия после завершения цикла. По моему опыту, он просто загромождает глобальное пространство имен и затрудняет отслеживание ошибок, которые могут быть уловлены переводчиками на других языках.

Ответ 1

Самый верный ответ заключается в том, что он просто упрощает грамматику, не стал камнем преткновения для принятия, и многие из них были довольны тем, что не должны были устранить сферу действия, к которой принадлежит имя, при назначении ей в рамках цикла, Переменные не объявляются в пределах области действия, это подразумевается расположением операторов присваивания. Ключевое слово global существует именно по этой причине (для обозначения того, что назначение выполняется в глобальной области).

Обновление

Здесь хорошее обсуждение по теме: http://mail.python.org/pipermail/python-ideas/2008-October/002109.html

Предыдущие предложения, чтобы сделать for-loop переменные, локальные в цикле, имеют наткнулся на проблему существующих код, который опирается на переменную цикла сохраняя свою ценность после выхода из и кажется, что это считается желательной особенностью.

Короче говоря, вы можете обвинить его в сообществе Python: P

Ответ 2

Python не имеет блоков, как и другие языки (например, C/С++ или Java). Таким образом, область видимости в Python является функцией.

Ответ 3

Действительно полезный случай для этого - при использовании enumerate и вы хотите общее количество в конце:

for count, x in enumerate(someiterator, start=1):
    dosomething(count, x)
print "I did something {0} times".format(count)

Это необходимо? Нет, но это конечно удобно.

Еще одна вещь, о которой нужно знать: в Python 2 переменные в списках также просочились:

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

Но то же самое не относится к Python 3.

Ответ 4

Если у вас есть оператор break в цикле (и вы хотите использовать значение итерации позже, возможно, чтобы выполнить резервное копирование, индексировать что-либо или присвоить статус), это сэкономит вам одну строку кода и одно присваивание, так что есть удобство.

Ответ 5

Одним из основных факторов, влияющих на Python, является ABC, язык, разработанный в Нидерландах для обучения программированию концепций для начинающих. Создатель Python, Гвидо ван Россум, несколько лет работал над ABC в 1980-х годах. Я почти ничего не знаю о ABC, но поскольку он предназначен для начинающих, я предполагаю, что он должен иметь ограниченное количество областей, так же, как ранние Бейсики.

Ответ 6

Для начала, если переменные были локальными для циклов, эти циклы были бы бесполезны для большинства программ реального мира.

В текущей ситуации:

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

дает 45. Теперь рассмотрим, как назначение работает в Python. Если переменные цикла были строго локальными:

# 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

дает 0, потому что total внутри цикла после назначения не является той же переменной, что и total вне цикла. Это не было бы оптимальным или ожидаемым поведением.