为何需要else: pass才能继续处理?
有人能解释一下为什么下面的 else: pass
是必须的,才能让后面的代码(最后的 print 'processing...'
语句)被执行吗?注意,else
中的 print
只是为了让我确认代码确实走到了这条路径。
看起来只要没有执行 continue
,代码就应该继续执行 else
中的内容,因为 else
里的代码什么也不做。但是,如果我把 else
去掉,当条件为假时——也就是目录中确实存在以 do 结尾的文件——for
循环中的其他部分似乎就不再执行了,这让我很困惑。文档上说 continue
是“继续执行最近的外层循环的下一个周期”,这没问题,但如果没有执行 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)
谜团解开了
这个看似奇怪的行为其实是因为缩进的问题,这在上面的代码中看不出来,也通常在我的文本编辑器中看不到。结果发现最后的 print
语句缩进了3个空格加一个制表符,这让它看起来和 else
对齐,但实际上它要么是在 else
中的 pass
后面,要么是在 if
的第一部分中的 continue
后面。这显然让我很困惑。
这是我在文本编辑器中打开“显示空格/制表符”选项时的代码截图。红点代表空格,红色右尖引号(»
)代表一个制表符:
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
注意“processing”行的存在。
然后我用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"
请注意,“processing”行没有任何差异。
我打算自己回答这个问题,最后还会接受这个答案。看起来奇怪的行为其实是因为一个微妙的缩进问题引起的,这个可能性是用户@delnan首先提醒我的。因为这个问题是看不见的,起初我没想到会是这个原因,但经过进一步调查后,我最终找到了它。相关的细节我已经加在问题的最后面了。