2016-10-08 3 views
1

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

Очевидный случай использования заключается в следующем:

x = default_value 
for x in iterator: 
    # do stuff 
# do something with x here 

К сожалению, часто первая линия забыто:

# should have set default value for x here 
# but forgot 
for x in iterator: 
    # do stuff 
# do something with x here 

Итак, когда итератор пуст, они поднимают NameError если x не было определено ранее.

Эта ошибка становится хуже с вложенными циклами:

for y in outer_iterator: 
    # should have set default value for x here 
    # but forgot 
    for x in inner_iterator(y): 
     # do stuff 
    # do something with x 

Здесь забывая x = default_value результатов в молчаливых ошибках вместо исключения, если inner_iterator(y) пуст на второй или более позднюю итерации внешнего цикла.

Тестирование этих ситуаций является трудным, потому что inner_iterator(y) не является внешним аргументом, поэтому, если тест не повезет, чтобы как-то воссоздать случай, когда он пуст, ошибка не будет обнаружена.

Все ли случаи использования хрупкие или существует безопасный способ полагаться на правило определения переменных for-loop?

ответ

0

Существует нет 100% безопасного способа полагаться на переменную, установленную внутри цикла for, если вы не можете быть на 100% уверены, что итератор никогда не пуст. Чтобы достичь 100% -ной уверенности, вы можете сделать что-то вроде for x in iterator or [None]:, но это создает аналогичную проблему «помня, чтобы сделать это». Вероятно, это скорее «pythonic», чем установка значений по умолчанию, но значения по умолчанию могут обеспечить большую ясность. Все, что полагается на просмотр в петле, похоже на что-то вроде if (condition): x = something, а затем размышляя о том, что, если я назову x, когда условие ложно? Вероятно, вы все равно не будете писать такой код, так зачем это делать для циклов? Мне нравится объявлять все переменные, которые будут использоваться вне upfront (например, установка всех переменных в None или какой-либо другой по умолчанию в начале функции), но это просто сводится к предпочтению.

0

Я согласен с тем, что наиболее очевидная причина, по которой петли не имеют собственной области видимости, - это осложнения, которые могут возникнуть при присвоении значений переменным во внешней области.

Но это не обязательно означает итерированное значение. Учитывайте следующее:

total = 0 
for item in some_list: 
    total += item 

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

Одним из onsequences является то, что item также avaialable из петли, но это на самом деле не означает, что есть хороший способ (или, как вы говорите «безопасный» путь), чтобы использовать его.

Вы можете использовать его, но тогда вам нужно быть осторожным.

Смежные вопросы