我理解这种结构是如何运作的:

for i in range(10):
    print(i)

    if i == 9:
        print("Too big - I'm giving up!")
        break
else:
    print("Completed successfully")

但我不明白为什么在这里使用else作为关键字,因为它表明有问题的代码只在for块未完成时运行,这与它所做的相反!无论我怎么想,我的大脑都不能从for语句无缝地过渡到else语句块。对我来说,continue和continuouswith更有意义(我正试着训练自己这样读它)。

我想知道Python程序员是如何在头脑中(或者大声地,如果你喜欢)阅读这个结构的。也许我遗漏了一些可以使这些代码块更容易破译的东西?


这个问题是关于底层设计决策的,也就是说,为什么能够编写这些代码是有用的。另请参阅Python while语句中的Else子句,了解语法含义的具体问题。


当前回答

一个常见的构造是运行一个循环,直到找到一些东西,然后跳出循环。问题是,如果我跳出循环或循环结束,我需要确定发生了哪种情况。一种方法是创建一个标志或存储变量,让我进行第二次测试,以查看循环是如何退出的。

例如,假设我需要在列表中搜索并处理每个项,直到找到标志项,然后停止处理。如果缺少标志项,则需要引发异常。

使用Python进行…你的其他构念

for i in mylist:
    if i == theflag:
        break
    process(i)
else:
    raise ValueError("List argument missing terminal flag.")

将此方法与不使用此语法糖的方法进行比较:

flagfound = False
for i in mylist:
    if i == theflag:
        flagfound = True
        break
    process(i)

if not flagfound:
    raise ValueError("List argument missing terminal flag.")

在第一种情况下,raise与它所使用的for循环紧密绑定。第二种情况是,绑定不那么牢固,在维护过程中可能会出现错误。

其他回答

这里是搜索之外的另一个惯用用例。假设您希望等待一个条件为真,例如,远程服务器上的一个端口打开,并伴有一些超时。然后你可以利用一点时间…其他结构如下:

import socket
import time

sock = socket.socket()
timeout = time.time() + 15
while time.time() < timeout:
    if sock.connect_ex(('127.0.0.1', 80)) is 0:
        print('Port is open now!')
        break
    print('Still waiting...')
else:
    raise TimeoutError()

我把它读成这样:“当可迭代对象完全耗尽时,在完成for语句后,执行即将继续执行下一个语句,else子句将被执行。”因此,当迭代被break打断时,这将不会执行。

因为他们不想给这门语言引入一个新的关键字。每一个都窃取一个标识符并导致向后兼容问题,所以通常是最后的手段。

我是这样读的:

如果还在运行循环的条件下,做点别的,否则做点别的。

我只是想让自己重新理解一下。我发现下面的方法很有用!

•将else看作是与循环中的if配对(而不是与for配对)-如果条件满足,则打破循环,否则执行此操作-除非它是与多个if配对的else ! •如果所有的“如果”都不满足,那么就做“其他”。 •多个如果实际上也可以被认为是if-elifs!