为什么else在for/while语句中表现不同于if/try语句?
我最近发现了Python在处理不同复合语句中的else部分时似乎有些不一致。因为Python设计得很好,我相信一定有合理的解释,但我一时想不起来。
看看下面的例子:
if condition:
do_something()
else:
do_something_else()
在这里,do_something_else()
只有在 condition
为假时才会执行,这很正常。
类似地,在
try:
do_something()
except someException:
pass:
else:
do_something_else()
finally:
cleanup()
do_something_else()
只有在没有发生异常时才会执行。
但是在for循环或while循环中,无论 for/while块
的内容是否被执行,else部分总是会被执行。
for i in some_iterator:
print(i)
else:
print("Iterator is empty!")
无论我写 some_iterator = []
还是 some_iterator = [1,2,3]
,都会打印 "Iterator is empty!"。在 while-else
语句中也是同样的行为。在这些情况下,else
的表现更像是 finally
。我是不是漏掉了什么?
3 个回答
没错,正如Eli提到的,else部分只有在你没有使用break的时候才会执行。这可以防止你写出像下面这样的代码:
for i in range(1,10):
if i % 5 == 0:
print i
break
if i % 5 != 0:
print "nothing divisible by 5"
虽然在这里它们的效果差不多,但如果退出的条件比较复杂(比如需要检查多种可能的条件或条件组合),这样写就很方便了。
在编程中,for else
这个结构的意思是,如果在循环中没有执行过 break
语句,那么就会执行 else
里面的内容。你可以把 break
想象成一个“中断”指令,它会让循环提前结束。比如说,下面这个 else
的内容是不会被执行的:
for i in range(1,10):
if i % 5 == 0:
print i
break
else:
print "nothing divisible by 5"
这要看你怎么理解了。你可以把else看成这样(抱歉用大写字母强调,这是代码中唯一的强调方式):
if condition:
do_something()
IF THE PREVIOUS CONDITION WAS FALSE:
do_something_else()
现在,if/else和try/except/else之间有明显的相似之处,如果你把else看作是except的else。就像这样。
try:
do_something()
IF THERE WAS AN EXCEPTION:
pass:
IF THE PREVIOUS CONDITION WAS FALSE:
do_something_else()
finally:
cleanup()
else/for也是一样的:
IF some_iterator IS NOT EMPTY:
i = next(some_iterator)
print(i)
IF THE PREVIOUS CONDITION WAS FALSE:
print("Iterator is empty!")
所以在某种基本的意义上,所有这三种情况中的else确实是以完全相同的方式工作的。
但你也可以这样理解else:
try:
do_something()
except someException:
pass:
IF NO EXCEPTION:
do_something_else()
finally:
cleanup()
这样一来,它就不再是一样的了,而是变成了一种“如果没有其他情况”。你也可以用同样的方式看待for/else:
for i in some_iterator:
print(i)
IF NO MORE ITERATING:
print("Iterator is empty!")
不过,再考虑到elif,这种理解方式同样适用于if/else:
if condition:
do_something()
elif otherconditaion:
do_anotherthing()
IF NO CONDITION WAS TRUE:
do_something_else()
你想怎么理解else取决于你自己,但无论哪种方式,else在这三种情况下确实有相似之处。