一、错误处理
使用try except 错误处理机制:
int()函数可能会抛出ValueError,所以我们用一个except捕获ValueError,用另一个except捕获ZeroDivisionError。
此外,如果没有错误发生,可以在except语句块后面加一个else,当没有错误发生时,会自动执行else语句:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
try: print('try...') r = 10 / int('2') print('result:',
r)except ValueError
as e: print('ValueError:',
e)except ZeroDivisionError
as e: print('ZeroDivisionError:',
e)else: print('no
error!')finally: print('finally...')print('END') |
使用try...except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用foo(),foo()调用bar(),结果bar()出错了,这时,只要main()捕获到了,就可以处理
记录错误:
使用logging模块
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#
err_logging.pyimport loggingdef foo(s): return 10 / int(s)def bar(s): return foo(s) * 2def main(): try: bar('0') except Exception
as e: logging.exception(e)main()print('END') |
同样是出错,但程序打印完错误信息后会继续执行,并正常退出
抛出错误:
因为错误是class,捕获一个错误就是捕获到该class的一个实例。因此,错误并不是凭空产生的,而是有意创建并抛出的。Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。
如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise语句抛出一个错误的实例:
|
1
2
3
4
5
6
7
8
9
10
11
|
#
err_raise.pyclass FooError(ValueError): passdef foo(s): n = int(s) if n==0: raise FooError('invalid
value: %s' % s) return 10 / nfoo('0') |
最后,我们来看另一种错误处理的方式:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#
err_reraise.pydef foo(s): n = int(s) if n==0: raise ValueError('invalid
value: %s' % s) return 10 / ndef bar(): try: foo('0') except ValueError
as e: print('ValueError!') raisebar() |
在bar()函数中,我们明明已经捕获了错误,但是,打印一个ValueError!后,又把错误通过raise语句抛出去了,这不有病么?
其实这种错误处理方式不但没病,而且相当常见。捕获错误目的只是记录一下,便于后续追踪。但是,由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理。好比一个员工处理不了一个问题时,就把问题抛给他的老板,如果他的老板也处理不了,就一直往上抛,最终会抛给CEO去处理。
二、调试
断言(assert)
|
1
2
3
4
5
6
7
|
def foo(s): n = int(s) assert n
!= 0, 'n
is zero!' return 10 / ndef main(): foo('0') |
assert的意思是,表达式n
!= 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。
如果断言失败,assert语句本身就会抛出AssertionError:
logging模块:
|
1
2
3
4
5
6
|
import logginglogging.basicConfig(level=logging.INFO)s = '0'n = int(s)logging.info('n
= %d' % n)print(10 / n) |
这就是logging的好处,它允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。
三、测试
一、错误处理
使用try except 错误处理机制:
int()函数可能会抛出ValueError,所以我们用一个except捕获ValueError,用另一个except捕获ZeroDivisionError。
此外,如果没有错误发生,可以在except语句块后面加一个else,当没有错误发生时,会自动执行else语句:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
try: print('try...') r = 10 / int('2') print('result:',
r)except ValueError
as e: print('ValueError:',
e)except ZeroDivisionError
as e: print('ZeroDivisionError:',
e)else: print('no
error!')finally: print('finally...')print('END') |
使用try...except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用foo(),foo()调用bar(),结果bar()出错了,这时,只要main()捕获到了,就可以处理
记录错误:
使用logging模块
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#
err_logging.pyimport loggingdef foo(s): return 10 / int(s)def bar(s): return foo(s) * 2def main(): try: bar('0') except Exception
as e: logging.exception(e)main()print('END') |
同样是出错,但程序打印完错误信息后会继续执行,并正常退出
抛出错误:
因为错误是class,捕获一个错误就是捕获到该class的一个实例。因此,错误并不是凭空产生的,而是有意创建并抛出的。Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。
如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise语句抛出一个错误的实例:
|
1
2
3
4
5
6
7
8
9
10
11
|
#
err_raise.pyclass FooError(ValueError): passdef foo(s): n = int(s) if n==0: raise FooError('invalid
value: %s' % s) return 10 / nfoo('0') |
最后,我们来看另一种错误处理的方式:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#
err_reraise.pydef foo(s): n = int(s) if n==0: raise ValueError('invalid
value: %s' % s) return 10 / ndef bar(): try: foo('0') except ValueError
as e: print('ValueError!') raisebar() |
在bar()函数中,我们明明已经捕获了错误,但是,打印一个ValueError!后,又把错误通过raise语句抛出去了,这不有病么?
其实这种错误处理方式不但没病,而且相当常见。捕获错误目的只是记录一下,便于后续追踪。但是,由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理。好比一个员工处理不了一个问题时,就把问题抛给他的老板,如果他的老板也处理不了,就一直往上抛,最终会抛给CEO去处理。
二、调试
断言(assert)
|
1
2
3
4
5
6
7
|
def foo(s): n = int(s) assert n
!= 0, 'n
is zero!' return 10 / ndef main(): foo('0') |
assert的意思是,表达式n
!= 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。
如果断言失败,assert语句本身就会抛出AssertionError:
logging模块:
|
1
2
3
4
5
6
|
import logginglogging.basicConfig(level=logging.INFO)s = '0'n = int(s)logging.info('n
= %d' % n)print(10 / n) |
这就是logging的好处,它允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。
三、测试

2万+

被折叠的 条评论
为什么被折叠?



