2013-02-15 2 views
0

Может кто-то объяснить причину, почему else:pass, показанный ниже, необходим для остатка кода (окончательного сообщения print 'processing...)? Обратите внимание, что print в else был помещен туда, чтобы я мог сказать, что исполнение действительно проходило по этому пути.Почему это еще: передать для продолжения обработку?

Кажется, что это должно происходить всякий раз, когда continue не выполняется, поскольку код в else ничего не делает. Однако, если я покину else, ничего больше в цикле for не будет выполняться, когда условие False - если в каталоге есть файлы с расширением do, что для меня не имеет смысла. Документы говорят, что continue «продолжается с последующим циклом ближайшего замкнутого цикла», штраф, но если он не выполняется, не следует ли переходить к следующему оператору?

import os 

source_dir = r'C:\Downloads' 
ext = '.mp3' 

for dirName, subdirList, fileList in os.walk(source_dir): 
    if not any(os.path.splitext(fileName)[1].lower() == ext for fileName in fileList): 
     print ' skipping "{}"'.format(dirName) 
     continue 
    else: # why is this clause needed to continue this iteration of a loop? 
     print 'contains "{}"'.format(dirName) 
     pass 

    print 'processing "{}" which has "{}" files'.format(dirName, ext) 

Mystery решаемые

Казалось бы, странное поведение было связано с проблемой вдавливания, которая не видна в выше, ни нормально в моем текстовом редакторе кода. Оказалось, что последнее высказывание print было отступом на 3 пробела, а затем на вкладке, которая, по-видимому, выравнивается с else, но на самом деле она либо следует за pass в else, если она есть, либо следует за continue в первой части if. Очевидно, меня много смущает.

Вот скриншот кода в текстовом редакторе с включенной опцией «show space/tabs». Красные точки представляют собой пространство, а красный >> представляет собой символ табуляции:

screenshot of file in my editor showing bad indentation

+1

Я уверен, что это необязательно. Я изменил '.mp3' на' .txt' и искал другой путь, но в противном случае я запустил код. Он работал как ожидалось в обоих случаях ... – mgilson

+3

Каков код, который не работает? (Кроме того, вы проверяли, что отступы согласуются, особенно при использовании пробелов/вкладок? Кажется, что это простое ограничение для такого рода ошибок, так как 'else' также можно привязать к' for'.) – delnan

+0

Я запустил ваш код и они ведут себя так, как ожидалось, в обоих случаях. –

ответ

1

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

4

Вам не нужны. Я побежал следующие 2 скрипта:

#test1.py 
import os 

source_dir = '.' 
ext = '.txt' 

for dirName, subdirList, fileList in os.walk(source_dir): 
    if not any(os.path.splitext(fileName)[1].lower() == ext for fileName in fileList): 
     print ' skipping "{}"'.format(dirName) 
     continue 
    else: # why is this clause needed to continue this iteration of a loop? 
     print 'contains "{}"'.format(dirName) 
     pass 

    print 'processing "{}" which has "{}" files'.format(dirName, ext) 

и

#test2.py 
import os 

source_dir = '.' 
ext = '.txt' 

for dirName, subdirList, fileList in os.walk(source_dir): 
    if not any(os.path.splitext(fileName)[1].lower() == ext for fileName in fileList): 
     print ' skipping "{}"'.format(dirName) 
     continue 
    #else: # why is this clause needed to continue this iteration of a loop? 
    # print 'contains "{}"'.format(dirName) 
    # pass 

    print 'processing "{}" which has "{}" files'.format(dirName, ext) 

Я побежал их:

python test1.py > junk.log 
python test2.py > junk.log2 

Вот первые пару строк junk.log:

test $ head junk.log 
processing "." which has ".txt" files 
    skipping "./new" 
    skipping "./unum" 
processing "./unum/kiv-unum-409befe069ac" which has ".txt" files 
    skipping "./unum/kiv-unum-409befe069ac/build" 
    skipping "./unum/kiv-unum-409befe069ac/build/bdist.macosx-10.3-fat" 
    skipping "./unum/kiv-unum-409befe069ac/build/lib" 
    skipping "./unum/kiv-unum-409befe069ac/build/lib/tests" 
    skipping "./unum/kiv-unum-409befe069ac/build/lib/unum" 
    skipping "./unum/kiv-unum-409befe069ac/build/lib/unum/units 

Notice наличие «pr перерабатывающих "линий.

diff Тогда я вывод:

diff junk.log junk.log2 

со следующими результатами:

0a1 
> contains "." 
3a5 
> contains "./unum/kiv-unum-409befe069ac" 
14a17 
> contains "./unum/kiv-unum-409befe069ac/docs" 
16a20 
> contains "./unum/kiv-unum-409befe069ac/nose-1.2.1-py2.7.egg/EGG-INFO" 
19a24 
> contains "./unum/kiv-unum-409befe069ac/nose-1.2.1-py2.7.egg/nose" 
30a36 
> contains "./unum/kiv-unum-409befe069ac/Unum.egg-info" 

Обратите внимание, что не существует никаких различий по "обработке" линий.

+0

Вы правы, похоже, что это не нужно, поэтому я задал вопрос. Оказывается, это была проблема с невидимым отступом, см. Обновление, которое я добавил к моему вопросу. Спасибо, хотя для подтверждения вещей - пока проблема не была найдена, я действительно задавал себе вопрос о том, как работает 'continue'. – martineau

+0

@martineau - Agrv! И я размышлял о том, что вы пытаетесь запустить его с помощью 'python -t' (или' python -tt') ... – mgilson

+0

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