在“除”块之后使用“else”块是否重要?

时间:2017-10-10 15:01:00

标签: python

我知道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

是首选吗?就翻译而言,他们甚至有什么不同吗?成功else后继续 总是try还是可以继续进行缩进,如number_of_foos1中那样?

1 个答案:

答案 0 :(得分: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科。所有这些代码都是无用的,并且会保证代码片段#1更简单并在主分支中返回结果。