【问题标题】:Is it important to use an "else" block after an "except" block?在“except”块之后使用“else”块是否重要?
【发布时间】:2018-03-22 01:13:34
【问题描述】:

我知道what a try-else block is,但考虑以下两个函数:

# Without else
def number_of_foos1(x):
    try:
       number = x['foo_count']
    except:
       return 0
    return number

# With else
def number_of_foos2(x):
    try:
       number = x['foo_count']
    except:
       return 0
    else:
       return number

x_with_foo = dict(foo_count=5)
x_without_foo = 3

this try-else question 不同,我们不会在try 块中添加额外的行。在这两种情况下,try 块都是一行,并且不违反将错误处理“接近”到导致它的错误的原则。

区别在于我们在成功的try 块之后去哪里。

在第一个块中,代码在except 块之后继续,在第二个块中,代码在else 处继续。

它们显然给出了相同的输出:

In [138]: number_of_foos1(x_with_foo)
Out[139]: 5

In [140]: number_of_foos1(x_without_foo)
Out[140]: 0

In [141]: number_of_foos2(x_with_foo)
Out[141]: 5

In [142]: number_of_foos2(x_without_foo)
Out[142]: 0

是首选吗?就口译员而言,它们甚至有什么不同吗?在成功的try 之后继续时,您应该总是有一个else,还是可以像number_of_foos1 那样不缩进继续?

【问题讨论】:

  • 在你的情况下,你是从 except 块返回的。所以是等价的。不回来怎么办?那是不等价的。
  • Python try-else的可能重复
  • 认为这个问题与提议的骗子略有不同。我将尝试解释如何,看看情况如何。 (也许并没有什么不同!)
  • @Jean-FrançoisFabre,是的,我认为这是关键的区别,不是吗?因为 except 块总是返回,所以不需要 else 块。

标签: python


【解决方案1】:

我会说你进入异常块的情况一定是罕见(也就是我们所说的异常)。因此,使用else 会过于重视该块,这在正常操作中不应该发生。

所以如果发生异常,处理错误并返回,然后忘记它。

这里使用else会增加复杂度,你可以通过反汇编这两个函数来确认:

>>> dis.dis(number_of_foos1)
  4           0 SETUP_EXCEPT            14 (to 17)

  5           3 LOAD_FAST                0 (x)
              6 LOAD_CONST               1 ('foo_count')
              9 BINARY_SUBSCR
             10 STORE_FAST               1 (number)
             13 POP_BLOCK
             14 JUMP_FORWARD            12 (to 29)

  6     >>   17 POP_TOP
             18 POP_TOP
             19 POP_TOP

  7          20 LOAD_CONST               2 (0)
             23 RETURN_VALUE
             24 POP_EXCEPT
             25 JUMP_FORWARD             1 (to 29)
             28 END_FINALLY

  8     >>   29 LOAD_FAST                1 (number)
             32 RETURN_VALUE

>>> dis.dis(number_of_foos2)
 <exactly the same beginning then:>

 15          20 LOAD_CONST               2 (0)
             23 RETURN_VALUE

             24 POP_EXCEPT
             25 JUMP_FORWARD             5 (to 33)
             28 END_FINALLY

 17     >>   29 LOAD_FAST                1 (number)
             32 RETURN_VALUE
        >>   33 LOAD_CONST               0 (None)
             36 RETURN_VALUE
>>> 

正如您在第二个示例中看到的,地址 24、25、28、33 和 36 无法访问,这是因为 Python 在代码末尾插入了跳转,并且在主分支中还有一个默认的 return None。所有这些代码都是无用的,并且会保证 sn-p #1 更简单并在主分支中返回结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 2011-09-20
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    相关资源
    最近更新 更多