python异常处理try...except 断言

python其它,专栏总目录

1.python异常处理

2.python正则表达式

 

高级语言通常都内置了一套try...except...finally...的错误处理机制。

1、try

1.1、try的机制

try:
    print('try...')
    r = 10 / 0
    print('result:', r)
except ZeroDivisionError as e:
    print('except:', e)
finally:
    print('finally...')
print('END')

当我们认为某些代码可能会出错时,就可以用try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,如果有finally语句块,则执行finally语句块,至此,执行完毕。

上面的代码在计算10 / 0时会产生一个除法运算错误,输出:

try...
except: division by zero
finally...
END

注:若所有的except都未正确捕获到异常,则错误最后被python解释器捕获。

1.2、深入讨论

1)try...else

如果没有错误发生,可以在except语句块后面加一个else,当没有错误发生时,会自动执行else语句,出错则不执行else:

try:
    print('try...')
    r = 10 / int('1')
    print('result:', r)
except ValueError as e:
    print('ValueError:', e)
else:
    print('no error!')
finally:
    print('finally...')
print('END')

没有错误时,执行try:->else:->finally:输出:

try...
result: 10.0
no error!
finally...
END

2)基类错误类型会屏蔽自类

Python的错误其实也是class,所有的错误类型都继承自BaseException,基类会捕获其所有子类错误类型。比如:

try:
    foo()
except ValueError as e:
    print('ValueError')
except UnicodeError as e:
    print('UnicodeError')

按照顺序捕获,第二个except永远也捕获不到UnicodeError,因为UnicodeError是ValueError的子类,如果有,也被第一个except给捕获了。

对于try...except语句,最好的写法是在最后添加一个公共基类的异常捕获,以确保try可以捕获所有异常。

except Exception as e:
    print('Exception:', e)

Python所有的错误都是从BaseException类派生的,常见的错误类型和继承关系看这里:

https://docs.python.org/3/library/exceptions.html#exception-hierarchy

3)跨越多层调用

使用try...except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用bar(),bar()调用foo(),结果foo()出错了,这时,只要main()捕获到了,就可以处理:

def foo(s):
    return 10 / int(s)

def bar(s):
    return foo(s) * 2

def main():
    try:
        bar('0')
    except Exception as e:
        print('Error:', e)
    finally:
        print('finally...')

也就是说,不需要在每个可能出错的地方去捕获错误,只要在合适的层次去捕获错误就可以了。这样一来,就大大减少了写try...except...finally的麻烦。

2、记录错误

Python内置的logging模块可以非常容易地记录错误信息:

import logging

try:
    ...
except Exception as e:
    logging.exception(e)

同样是出错,但程序打印完错误信息后会继续执行,并正常退出,通过配置,logging还可以把错误记录到日志文件里,方便事后排查。

3、断言

凡是用print()来辅助查看的地方,都可以用断言(assert)来替代:

def foo(s):
    n = int(s)
    assert n != 0, 'n is zero!'
    return 10 / n

def main():
    foo('0')

assert的意思是,表达式n != 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。如果断言失败,assert语句本身就会抛出AssertionError:

$ python err.py
Traceback (most recent call last):
  ...
AssertionError: n is zero!

程序中如果到处充斥着assert,和print()相比也好不到哪去。不过,启动Python解释器时可以用-O参数来关闭assert

$ python -O err.py
Traceback (most recent call last):
  ...
ZeroDivisionError: division by zero

  注意:断言的开关“-O”是英文大写字母O,不是数字0。关闭后,你可以把所有的assert语句当成pass来看。

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jingbo1801

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值