ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

08 | 异常处理:如何提高程序的稳定性?(下)

2021-06-18 23:55:33  阅读:172  来源: 互联网

标签:err format data 08 程序 稳定性 except try 异常


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

你好,我是悦创。

这一篇我们继续,前两篇可以进入公众号阅读。

用户自定义异常

前面的例子里充斥了很多 Python 内置的异常类型,你可能会问,我可以创建自己的异常类型吗?

答案是肯定是,Python 当然允许我们这么做。下面这个例子,我们创建了自定义的异常类型 MyInputError,定义并实现了初始化函数和 str 函数(直接 print 时调用):

  •  
class MyInputError(Exception):    """Exception raised when there're errors in input"""    def __init__(self, value): # 自定义异常类型的初始化        self.value = value    def __str__(self): # 自定义异常类型的string表达形式        return ("{} is invalid input".format(repr(self.value)))    try:    raise MyInputError(1) # 抛出MyInputError这个异常except MyInputError as err:    print('error: {}'.format(err))

如果你执行上述代码块并输出,便会得到下面的结果:

  •  
error: 1 is invalid input

实际工作中,如果内置的异常类型无法满足我们的需求,或者为了让异常更加详细、可读,想增加一些异常类型的其他功能,我们可以自定义所需异常类型。不过,大多数情况下,Python 内置的异常类型就足够好了。

 

异常的使用场景与注意点

学完了前面的基础知识,接下来我们着重谈一下,异常的使用场景与注意点。

通常来说,在程序中,如果我们不确定某段代码能否成功执行,往往这个地方就需要使用异常处理。除了上述文件读取的例子,我可以再举一个例子来说明。

大型社交网站的后台,需要针对用户发送的请求返回相应记录。用户记录往往储存在 key-value 结构的数据库中,每次有请求过来后,我们拿到用户的 ID,并用 ID 查询数据库中此人的记录,就能返回相应的结果。

而数据库返回的原始数据,往往是 json string 的形式,这就需要我们首先对 json string 进行 decode(解码),你可能很容易想到下面的方法:

  •  
import jsonraw_data = queryDB(uid) # 根据用户的id,返回相应的信息data = json.loads(raw_data)

这样的代码是不是就足够了呢?

要知道,在 json.loads() 函数中,输入的字符串如果不符合其规范,那么便无法解码,就会抛出异常,因此加上异常处理十分必要。try:

  •  
    data = json.loads(raw_data)    ....except JSONDecodeError as err:    print('JSONDecodeError: {}'.format(err))

不过,有一点切记,我们不能走向另一个极端——滥用异常处理。

比如,当你想要查找字典中某个键对应的值时,绝不能写成下面这种形式:

  •  
d = {'name': 'jason', 'age': 20}try:    value = d['dob']    ...except KeyError as err:    print('KeyError: {}'.format(err))

 

诚然,这样的代码并没有 bug,但是让人看了摸不着头脑,也显得很冗余。如果你的代码中充斥着这种写法,无疑对阅读、协作来说都是障碍。因此,对于 flow-control(流程控制)的代码逻辑,我们一般不用异常处理。

字典这个例子,写成下面这样就很好。

  •  
if 'dob' in d:    value = d['dob']    ...

总结

这节课, 我们一起学习了 Python 的异常处理及其使用场景,你需要重点掌握下面几点。

  • 异常,通常是指程序运行的过程中遇到了错误,终止并退出。我们通常使用 try except 语句去处理异常,这样程序就不会被终止,仍能继续执行。

  • 处理异常时,如果有必须执行的语句,比如文件打开后必须关闭等等,则可以放在 finally block 中。

  • 异常处理,通常用在你不确定某段代码能否成功执行,也无法轻易判断的情况下,比如数据库的连接、读取等等。正常的 flow-control 逻辑,不要使用异常处理,直接用条件语句解决就可以了。

思考题

最后,给你留一个思考题。在异常处理时,如果 try block 中有多处抛出异常,需要我们使用多个 try except block 吗?以数据库的连接、读取为例,下面两种写法,你觉得哪种更好呢?

第一种:

  •  
try:    db = DB.connect('<db path>') # 可能会抛出异常    raw_data = DB.queryData('<viewer_id>') # 可能会抛出异常except (DBConnectionError, DBQueryDataError) err:    print('Error: {}'.format(err))

第二种:

  •  
try:    db = DB.connect('<db path>') # 可能会抛出异常    try:        raw_data = DB.queryData('<viewer_id>')    except DBQueryDataError as err:         print('DB query data error: {}'.format(err))except DBConnectionError as err:     print('DB connection error: {}'.format(err))

标签:err,format,data,08,程序,稳定性,except,try,异常
来源: https://blog.51cto.com/aiyc/2926937

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有