|
5 | 5 | ---------- |
6 | 6 | 问题 |
7 | 7 | ---------- |
8 | | -You want to write code that catches all exceptions. |
| 8 | +怎样捕获代码中的所有异常? |
9 | 9 |
|
10 | 10 | | |
11 | 11 |
|
12 | 12 | ---------- |
13 | 13 | 解决方案 |
14 | 14 | ---------- |
15 | | -To catch all exceptions, write an exception handler for Exception, as shown here: |
| 15 | +想要捕获所有的异常,可以直接捕获 ``Exception`` 即可: |
16 | 16 |
|
17 | | -try: |
18 | | - ... |
19 | | -except Exception as e: |
20 | | - ... |
21 | | - log('Reason:', e) # Important! |
| 17 | +.. code-block:: python |
22 | 18 |
|
23 | | -This will catch all exceptions save SystemExit, KeyboardInterrupt, and GeneratorEx |
24 | | -it. If you also want to catch those exceptions, change Exception to BaseException. |
| 19 | + try: |
| 20 | + ... |
| 21 | + except Exception as e: |
| 22 | + ... |
| 23 | + log('Reason:', e) # Important! |
| 24 | +
|
| 25 | +这个将会捕获除了 ``SystemExit`` 、 ``KeyboardInterrupt`` 和 ``GeneratorExit`` 之外的所有异常。 |
| 26 | +如果你还想捕获这三个异常,将 ``Exception`` 改成 ``BaseException`` 即可。 |
25 | 27 |
|
26 | 28 | | |
27 | 29 |
|
28 | 30 | ---------- |
29 | 31 | 讨论 |
30 | 32 | ---------- |
31 | | -Catching all exceptions is sometimes used as a crutch by programmers who can’t re‐ |
32 | | -member all of the possible exceptions that might occur in complicated operations. As |
33 | | -such, it is also a very good way to write undebuggable code if you are not careful. |
34 | | -Because of this, if you choose to catch all exceptions, it is absolutely critical to log or |
35 | | -report the actual reason for the exception somewhere (e.g., log file, error message print‐ |
36 | | -ed to screen, etc.). If you don’t do this, your head will likely explode at some point. |
37 | | -Consider this example: |
38 | | - |
39 | | -def parse_int(s): |
40 | | - try: |
41 | | - n = int(v) |
42 | | - except Exception: |
43 | | - print("Couldn't parse") |
| 33 | +捕获所有异常通常是由于程序员在某些复杂操作中并不能记住所有可能的异常。 |
| 34 | +如果你不是很细心的人,这也是编写不易调试代码的一个简单方法。 |
44 | 35 |
|
45 | | -If you try this function, it behaves like this: |
| 36 | +正因如此,如果你选择捕获所有异常,那么在某个地方(比如日志文件、打印异常到屏幕)打印确切原因就比较重要了。 |
| 37 | +如果你没有这样做,有时候你看到异常打印时可能摸不着头脑,就像下面这样: |
46 | 38 |
|
47 | | ->>> parse_int('n/a') |
48 | | -Couldn't parse |
49 | | ->>> parse_int('42') |
50 | | -Couldn't parse |
51 | | ->>> |
| 39 | +.. code-block:: python |
52 | 40 |
|
53 | | -At this point, you might be left scratching your head as to why it doesn’t work. Now |
54 | | -suppose the function had been written like this: |
| 41 | + def parse_int(s): |
| 42 | + try: |
| 43 | + n = int(v) |
| 44 | + except Exception: |
| 45 | + print("Couldn't parse") |
55 | 46 |
|
56 | | -def parse_int(s): |
57 | | - try: |
58 | | - n = int(v) |
59 | | - except Exception as e: |
60 | | - print("Couldn't parse") |
61 | | - print('Reason:', e) |
| 47 | +试着运行这个函数,结果如下: |
| 48 | + |
| 49 | +:: |
| 50 | + |
| 51 | + >>> parse_int('n/a') |
| 52 | + Couldn't parse |
| 53 | + >>> parse_int('42') |
| 54 | + Couldn't parse |
| 55 | + >>> |
| 56 | + |
| 57 | +这时候你就会挠头想:“这咋回事啊?” 假如你像下面这样重写这个函数: |
| 58 | + |
| 59 | +.. code-block:: python |
| 60 | +
|
| 61 | + def parse_int(s): |
| 62 | + try: |
| 63 | + n = int(v) |
| 64 | + except Exception as e: |
| 65 | + print("Couldn't parse") |
| 66 | + print('Reason:', e) |
| 67 | +
|
| 68 | +这时候你能获取如下输出,指明了有个编程错误: |
62 | 69 |
|
63 | | -In this case, you get the following output, which indicates that a programming mistake |
64 | | -has been made: |
| 70 | +:: |
65 | 71 |
|
66 | | ->>> parse_int('42') |
67 | | -Couldn't parse |
68 | | -Reason: global name 'v' is not defined |
69 | | ->>> |
| 72 | + >>> parse_int('42') |
| 73 | + Couldn't parse |
| 74 | + Reason: global name 'v' is not defined |
| 75 | + >>> |
70 | 76 |
|
71 | | -All things being equal, it’s probably better to be as precise as possible in your exception |
72 | | -handling. However, if you must catch all exceptions, just make sure you give good di‐ |
73 | | -agnostic information or propagate the exception so that cause doesn’t get lost. |
| 77 | +很明显,你应该尽可能将异常处理器定义的精准一些。 |
| 78 | +不过,要是你必须捕获所有异常,确保打印正确的诊断信息或将异常传播出去,这样不会丢失掉异常。 |
0 commit comments