我知道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
中那样?
答案 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更简单并在主分支中返回结果。