资讯

展开

Python异常处理:让你的程序更稳定

作者:快盘下载 人气:

Python异常处理:让你的程序更稳定

Python异常处理:让你的程序更稳定

这两天在赶一个线上的程序,用python比较多,整理一点python异常相关的内容。好久没写代码,python功力又下降了,不得不说,啥技能都是要细细打磨的,不用了,忘得就很快。

01 异常和错误的区分

在python中,我们区分"异常"和"错误"这两个概念。错误,指的是语法不符合编码规范,无法被识别和执行。异常,指的是语法正确,可以被执行,但是在执行过程中遇到了问题,抛出异常。简单举个例子:

[root@VM-0-14-centos ~]# python
Python 2.7.5 (default, Aug  7 2019, 00:51:29) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
---------错误----------
>>> if aaa
  File "<stdin>", line 1
    if aaa
         ^
SyntaxError: invalid syntax
>>> 
---------异常--------
>>> 10/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDiVisionError: integer division or modulo by zero

如上所述,if aaa因为后面没有冒号,所以是语法错误,会报一个SyntaxError,表示语法错误;而10/0是因为分母不能为0,所以抛出了异常。

02 python中的常见异常

在写程序的过程中,会遇到各种各样的异常,例如:

keyError:代表字典里面找不到值;

FileNotFoundError:读取文件的时候,文件不存在;

ZeroDevisionError:分母不能为0;

NameError:变量没有声明直接使用,例如直接写a*2;

TypeError:变量类型错误,例如1+[1,2];

更详细的异常种类,大家可以看Python的官方文档:

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

这里就不再赘述了。

03 如何处理异常?try...execept

通常情况下,在Python中我们使用try...execept来处理异常。

如下是使用try execept来捕获一个NameError:

-----测试代码----
[root@VM-0-14-centos hotfix]# cat aa.py 
# /usr/bin/env python
try: 
  a*2
except NameError as err:
  e=err 
  print e   
print('hello,world')

------执行结果----
[root@VM-0-14-centos hotfix]# python aa.py 
name 'a' is not defined
hello,world

可以看到,我们的a没有定义,直接乘以2,就发生了NameError,然后我们使用execept将异常保存在err这个变量里面,又赋值给e这个变量,最后打印。

值得注意的是,代码最后面的hello,world也被执行了。

上面的情况下,我们已知异常类型是NameError,然后取捕捉NameError,当然能够捕捉到,如果我们写错了异常类型呢?见下面的代码:

----测试代码---
[root@VM-0-14-centos hotfix]# cat bb.py 
# /usr/bin/env python
try: 
  a*2
except TypeError as err:
  e=err 
  print e   
print('hello,world')

----输出结果----
[root@VM-0-14-centos hotfix]# python bb.py 
Traceback (most recent call last):
  File "bb.py", line 3, in <module>
    a*2
NameError: name 'a' is not defined

这次我们修改异常类型为TypeError,然后执行代码,可以看到异常被抛出来了,但是似乎没有上次的输出那么优雅,因为我们没有用TypeError捕获到,所以except后面的内容就没有输出。同时需要注意,最后一行的print语句也没有执行。

通过这两个小例子,可以看到:

1、只有异常类型相符的异常被捕获,才会执行except 代码块的内容,同时也会执行后续内容;

2、如果某个异常没有被捕获,那么后续的代码不会执行;

那么如何解决上面的问题呢?

假如我们知道异常可能是NameError或者TypeError,可以通过下面两种方法来保证能够捕获:

----方法一---
# /usr/bin/env python
try: 
  a*2
except NameError as err:
    print(err)
except TypeError as err:
    print(err)
print('hello,world')

----方法二----
# /usr/bin/env python
try: 
  a*2
except (NameError, TypeError) as err:
    print(err)
print('hello,world')

如果我们连具体的异常类型都不知道呢?这个时候,就可以使用Python中的异常基类Exception来进行捕获:

----方法三---
# /usr/bin/env python
try: 
  a*2
except Exception as err:
    print(err)

----方法四----(缺省表示Exception)
# /usr/bin/env python
try: 
  a*2
except:
    print('err')

需要注意:当一个程序中try后面跟有多个exception的时候,会匹配第一个可以匹配的异常类型。

04 容易忽略的finally

finally这个语法经常会在开发的时候忘记,下面是一个典型的例子:

import sys
try:
f = open('aaa.txt', 'r')
   # some data Processing
except OSError as err:
   print('OS error: {}'.format(err))
except:
   print('Unexpected error:', sys.exc_info()[0])
finally:
   f.close()

代码的内容是打开一个文件,然后做一些操作,操作过程中如果遇到了异常,则捕获这些异常。

上面的写法中,无论程序中的try语法模块中的操作执行成功还是失败,都会执行最后面的finally,finally语法最后面经常会写一些无论如何都要执行的语句。

异常处理的使用需要根据场景来确定,不能不用,不用的话代码稳定性不高;也不能滥用,滥用的话,会显得代码很冗余。

例如下面的2个小场景:

----场景一----
try:
    data = json.loads(raw_data)
except JSONDecodeError as err:
    print('JSONDecodeError: {}'.format(err))
解析json前,对json进行合法性判断是有必要的,
否则json的解析就会报错。

---场景二----
d = {'name': 'jason', 'age': 20}
try:
    value = d['dob']
except KeyError as err:
    print('KeyError: {}'.format(err))
字典的key值解析这种写法也可以,但是显得有点繁琐
最好的写法是:
if 'dob' in d:
   xxxxx

加载全部内容

相关教程
猜你喜欢
用户评论
快盘暂不提供评论功能!