关于异常:什么时候需要在Python中的try..except中添加`else`子句?

when is it necessary to add an `else` clause to a try..except in Python?

当我用Python编写带有异常处理的代码时,我可以编写如下代码:

1
2
3
4
5
6
try:
    some_code_that_can_cause_an_exception()
except:
    some_code_to_handle_exceptions()
else:
    code_that_needs_to_run_when_there_are_no_exceptions()

这与以下情况有何不同:

1
2
3
4
5
6
try:
    some_code_that_can_cause_an_exception()
except:
    some_code_to_handle_exceptions()

code_that_needs_to_run_when_there_are_no_exceptions()

在这两种情况下,如果没有例外,则执行code_that_needs_to_run_when_there_are_no_exceptions()。有什么区别?


在第二个示例中,当您确实有一个异常,然后处理它时,将运行code_that_needs_to_run_when_there_are_no_exceptions(),在except之后继续。

所以…

在这两种情况下,当有异常时,需要运行的代码将不会在没有异常时执行,但在没有异常时,后者将在有异常和没有异常时执行。

在CLI上尝试此操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/usr/bin/python

def throws_ex( raise_it=True ):
        if raise_it:
                raise Exception("Handle me")

def do_more():
        print"doing more
"


if __name__ =="__main__":
        print"Example 1
"

        try:
                throws_ex()
        except Exception, e:
                # Handle it
                print"Handling Exception
"

        else:
                print"No Exceptions
"

                do_more()

        print"example 2
"

        try:
                throws_ex()
        except Exception, e:
                print"Handling Exception
"

        do_more()

        print"example 3
"

        try:
                throws_ex(False)
        except Exception, e:
                print"Handling Exception
"

        else:
                do_more()

        print"example 4
"

        try:
                throws_ex(False)
        except Exception, e:
                print"Handling Exception
"

        do_more()

它将输出

Example 1

Handling Exception

example 2

Handling Exception

doing more

example 3

doing more

example 4

doing more

你得到了这个主意,玩一些例外,冒泡和其他的事情!打开命令行和VIM!


实际上,在第二个片段中,最后一行始终执行。

你可能是说

1
2
3
4
5
try:
    some_code_that_can_cause_an_exception()
    code_that_needs_to_run_when_there_are_no_exceptions()
except:
    some_code_to_handle_exceptions()

我相信如果它使代码更可读,您可以使用else版本。如果您不想从code_that_needs_to_run_when_there_are_no_exceptions捕获异常,您可以使用else变体。


例1:

1
2
3
4
5
try:
    a()
    b()
except:
    c()

这里,只有当a()没有抛出时,b()才会运行,但是except块也会捕获可能被b()抛出的任何异常,而这些异常可能是您不想要的。一般规则是:只捕获可能发生的异常(并有一种处理方法)。因此,如果你不知道b()是否会抛出,或者如果你无法通过捕获b()抛出的异常来做任何有用的事情,那么不要将b()放入try:块中。

例2:

1
2
3
4
5
6
try:
    a()
except:
    c()
else:
    b()

在这里,只有当a()没有抛出时,b()才会运行,但是任何b()抛出的异常都不会在这里捕获,并将继续向堆栈上传播。这常常是你想要的。

例3:

1
2
3
4
5
6
try:
    a()
except:
    c()

b()

在这里,b()总是运行的,即使a()没有抛出任何东西。当然,这也非常有用。


您的原始代码几乎是正确的。以下是完整的治疗方法:

1
2
3
4
5
6
7
8
try:
    some_code_that_can_cause_an_exception()
except:
    some_code_to_handle_exceptions()
else:
    code_that_needs_to_run_when_there_are_no_exceptions()

code_that_runs_whether_there_was_an_exception_or_not()


虽然内德·巴切尔德的回答适合这一行动,但我想在此基础上稍作改进。另外,我不能作为对mk12评论的评论来回复(因为我"只"有49个代表,而不是50个代表,去图)。所以我的贡献是:

1
2
3
4
5
6
7
8
9
10
11
12
try:
    code_that_can_cause_an_exception()
except ParticularException:
    code_to_handle_the_particular_exception()
except:
    code_to_handle_all_other_exceptions()
else:
    code_to_run_when_there_are_no_exceptions_and_which_should_not_be_run_after_except_clauses()
finally:
    code_to_run_whether_there_was_an_exception_or_not_even_if_the_program_will_exit_from_the_try_block()

code_to_run_whether_there_was_an_exception_or_not_if_execution_reaches_here()

我用Try:…除了:…否则:很多!

这是一个模式:Try..Except应该只跨越一行代码,在其中我预测到一个异常。然后,除了执行回退/默认处理,还有:我真的想做什么(没有例外=>继续做我想做的事情)。

一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
   # Exhibit 1
   data_paths = []
   try:
       from . import version_subst
   except ImportError:
       first_datadir ="./data"
   else:
       first_datadir = os.path.join(version_subst.DATADIR, PACKAGE_NAME)


# Exhibit 2
for attr in attrs:
    try:
        obj = getattr(plugin, attr)
    except AttributeError, e:
        if warn:
            pretty.print_info(__name__,"Plugin %s: %s" % (plugin_name, e))
        yield None
    else:
        yield obj


根据文件……

"如果控件从try子句结尾流出,则执行可选的else子句。前面的except子句不处理else子句中的7.2异常。"

所以看看这个基本的例子作为你的答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
try:
  print("Try with Exception")
  print(sys.path)
except NameError:
  print"Exception"
else:
  print"Else"

print("Out of try/except block")

try:
  print("Try without Exception")
except NameError:
  print"Exception"
else:
  print"Else is now executed"

print("Out of try/except finally")

查看在没有发生异常时如何执行其他操作。


我已经很久没有使用Python了,但是我尝试在EDCOX1的16个块中处理特定的异常,并且使用EDCOX1 OR 0来处理我可能没有想到的"其他"异常,类似于C/C++ EDCOX1×19个块中的EDCOX1×18块。这是否也适用于else