为何需要else: pass才能继续处理?

5 投票
2 回答
22675 浏览
提问于 2025-04-17 16:01

有人能解释一下为什么下面的 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 后面。这显然让我很困惑。

这是我在文本编辑器中打开“显示空格/制表符”选项时的代码截图。红点代表空格,红色右尖引号(»)代表一个制表符:

screenshot of file in my editor showing bad indentation

2 个回答

6

你不需要这个。我运行了以下两个脚本:

#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”行没有任何差异。

5

我打算自己回答这个问题,最后还会接受这个答案。看起来奇怪的行为其实是因为一个微妙的缩进问题引起的,这个可能性是用户@delnan首先提醒我的。因为这个问题是看不见的,起初我没想到会是这个原因,但经过进一步调查后,我最终找到了它。相关的细节我已经加在问题的最后面了。

撰写回答