为啥会这样:处理需要通过才能继续? [关闭]

Posted

技术标签:

【中文标题】为啥会这样:处理需要通过才能继续? [关闭]【英文标题】:Why is this else: pass needed for processing to continue? [closed]为什么会这样:处理需要通过才能继续? [关闭] 【发布时间】:2013-02-15 18:12:39 【问题描述】:

有人可以解释为什么需要下面显示的else: pass 才能执行其余代码(最后的print 'processing... 语句)吗?请注意 else 中的 print 被放在那里只是为了让我知道执行确实是在走这条路。

似乎每当continue 没有执行时就会发生这种情况,因为else 中的代码什么都不做。但是,如果我将 else 排除在外,则当条件为 False 时,for 循环中似乎不会执行任何进一步的操作——当目录中存在扩展名为 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)

谜团解开

看似奇怪的行为是由于缩进问题造成的,这在上面的代码中不可见,通常在我的文本编辑器中也不可见。事实证明,最后一个 print 语句缩进了 3 个空格,然后是一个制表符,这使它看起来与 else 对齐,但实际上它要么遵循 else 中的 pass,如果它在那里,或在if 的第一部分跟随continue。显然让我很困惑。

这是我的文本编辑器中打开“显示空间/标签”选项的代码的屏幕截图。红点代表空格,红色右 guillemet (») 代表制表符:

【问题讨论】:

我很确定没有必要。我将.mp3 更改为.txt 并搜索了不同的路径,否则我运行了您的代码。它在两种情况下都按预期工作...... 什么代码不起作用? (另外,您是否检查过缩进是否一致,尤其是在使用空格/制表符时?似乎是此类错误的主要候选者,因为else 也可以附加到for。) 我运行了您的代码,在这两种情况下,它的行为都符合预期。 如果该块中有另一个语句(在本例中为 print),则永远不需要 pass @delnan:是的,我确定缩进是正确的。问题是如果我注释掉else: 和它后面的两行,print 'processing... 永远不会发生。但是,在 else: 中,print 'contains... 每次都会执行,然后是 print 'processing... - 所以 else: 似乎是后者发生所必需的。 【参考方案1】:

你不需要它。我运行了以下 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

注意“处理”行的存在。

然后我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"

请注意,“处理”行没有区别。

【讨论】:

你说得对,似乎不需要它,这就是我问这个问题的原因。原来这是一个不可见的缩进问题,请参阅我添加到问题中的更新。感谢您的确认——在发现问题之前,我一直在质疑自己对 continue 工作原理的理解。 @martineau -- Agrv!我正在考虑建议您尝试使用python -t(或python -tt)运行它... 很好的建议......在我再次出丑之前,我会尽量记住使用它,然后再问一个关于菜鸟错误导致的问题的问题。从某种意义上说,这确实是一场完美的风暴,在这种情况下,错误的缩进是由一个不可见的地方的标签引起的,并且改变了逻辑,而不是导致这种事情通常导致的更明显的错误之一。 【参考方案2】:

我将回答我自己的问题并最终接受它。所描述的看似奇怪的行为是由一个微妙的缩进问题引起的,用户@delnan 首先引起了我的注意。因为它是隐形的,所以一开始我觉得不会是这样,但经过更多的调查最终发现了它。其中的详细信息已添加到我的问题的末尾。

【讨论】:

以上是关于为啥会这样:处理需要通过才能继续? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我需要按两次后退按钮才能第一次关闭片段?

为啥需要关闭另一个进程的管道加上 set_close_on_exec 才能真正关闭?

与 C 和 C++ 相比,为啥 c# 代码需要很长时间才能执行 [关闭]

UAC是啥?如何关闭UAC

为啥 chromecast 需要互联网?

金蝶KIS专业版,听说在不注册的情况下,可以免费使用三个月,三个月后,需要注册才能继续使用,是这样