为啥会这样:处理需要通过才能继续? [关闭]
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 才能真正关闭?