为什么在Python的`finally`子句中不允许`continue`?

Ele*_*naT 41 python continue finally syntax-error

以下代码引发语法错误:

>>> for i in range(10):
...     print i
...     try:
...        pass
...     finally:
...        continue
...     print i
...
  File "<stdin>", line 6
SyntaxError: 'continue' not supported inside 'finally' clause
Run Code Online (Sandbox Code Playgroud)

为什么continuefinally条款中不允许声明?

PS另一方面,这个其他代码没有问题:

>>> for i in range(10):
...     print i
...     try:
...        pass
...     finally:
...        break
...
0
Run Code Online (Sandbox Code Playgroud)

如果重要,我使用的是Python 2.6.6.

Ray*_*ger 27

禁止在finally子句中使用continue,因为它的解释会有问题.如果finally子句因异常而被执行,你会怎么做?

for i in range(10):
    print i
    try:
       raise RuntimeError
    finally:
       continue        # if the loop continues, what would happen to the exception?
    print i
Run Code Online (Sandbox Code Playgroud)

我们可以决定这个代码应该做什么,也许可以吞下异常; 但良好的语言设计则表明不然.如果代码混淆了读者,或者有更清晰的方式来表达预期的逻辑(可能还有try: ... except Exception: pass; continue),那么将其作为SyntaxError存在一些优势.

有趣的是,您可以在finally子句中放置一个返回值,它将吞下所有异常,包括KeyboardInterrupt,SystemExitMemoryError.这也许不是一个好主意;-)

  • 我同意.如果异常中断了您的过程,则finally子句的使用通常会占用松散的末尾.如果存在影响循环条件本身的问题,那么"最终继续"(在英语中也是荒谬的)将存在重复异常的风险,直到循环终止,或甚至无限重复它. (4认同)
  • finally块中的continue可以与return或raise相同的方式处理.在此示例中,将吞下异常并继续循环. (3认同)
  • 我想人们忘记了`finally`块中的代码总是被执行. (2认同)

Mic*_*man 6

Python语言参考禁止continuefinally子句中使用.我不完全确定为什么.也许是因为continuetry子句中确保finally执行,并且决定continuefinally子句中应该做什么有点含糊不清.

编辑:@Mike Christensen对该问题的评论指出了一个线程,其中Python核心开发人员讨论了这种结构的模糊性.此外,在使用超过九年的Python中,我从来没有想过这样做,所以开发人员不想花太多时间这可能是一种相对不常见的情况.

  • 在这些情况下,有时候不允许开发人员做某事更好 - 否则你必须规范,解决和修复因允许这类事情而产生的任何奇怪. (2认同)

wim*_*wim 6

由于实现问题,finally 子句中的 continue 语句是非法的。在 Python 3.8 中,这个限制被取消了。

该错误是issues32489 - 允许在“finally”子句中“继续”

修复的拉取请求:https://github.com/python/cpython/pull/5822