代码之家  ›  专栏  ›  技术社区  ›  Tim Pietzcker

为什么for/while语句中的else行为与if/try语句不同?

  •  6
  • Tim Pietzcker  · 技术社区  · 16 年前

    我最近偶然发现,在处理不同复合语句中的else子句时,python的方式似乎存在不一致。因为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()
    

    做点别的事 仅在未发生异常时执行。

    但在for或while循环中,始终执行else子句,无论 for/while block 是否已执行。

    for i in some_iterator:
       print(i)
    else:
       print("Iterator is empty!")
    

    将始终打印“迭代器为空!”,无论我说 some_iterator = [] some_iterator = [1,2,3] . 相同的行为 while-else 条款。在我看来 else 表现得更像 finally 在这些情况下。我忽略了什么?

    3 回复  |  直到 16 年前
        1
  •  5
  •   Lennart Regebro    16 年前

    嗯,这要看你怎么看。您可以这样看ELSE(请原谅尖叫声,这是在代码中强调重点的唯一方法):

    if condition:
       do_something()
    IF THE PREVIOUS CONDITION WAS FALSE:
       do_something_else()
    

    现在,如果您将else语句视为except语句的else,那么if/else和try/except/else之间存在明显的相似性。这样地。

    try:
       do_something()
    IF THERE WAS AN EXCEPTION:
       pass:
    IF THE PREVIOUS CONDITION WAS FALSE:
       do_something_else()
    finally:
       cleanup()
    

    对于其他/对于:

    IF some_iterator IS NOT EMPTY:
       i = next(some_iterator)
       print(i)
    IF THE PREVIOUS CONDITION WAS FALSE:
       print("Iterator is empty!")
    

    所以在这里,我们看到其他的一些基本的方式 在这三种情况下都是一样的。

    但你也可以用这种方式看到其他:

    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确实有相似之处。

        2
  •  13
  •   Eli Courtwright    16 年前

    这个 for else 构造执行 else 条款如果没有 break 为循环执行了语句, as described here 例如,从不计算此else子句

    for i in range(1,10):
        if i % 5 == 0:
           print i
           break
    else:
        print "nothing divisible by 5"
    
        3
  •  4
  •   Chris Harris    16 年前

    是的,正如Eli所提到的,只有在不中断时才会执行else子句。它阻止您实现这样的代码:

    for i in range(1,10):
        if i % 5 == 0:
           print i
           break
    if i % 5 != 0:
       print "nothing divisible by 5"
    

    这在这里大致相当,但是如果退出的条件更复杂一些(比如检查各种可能的条件或条件组合),这很方便。