Python异常及处理方法总结(python中如何处理异常)

网友投稿 2551 2022-08-28


Python异常及处理方法总结(python中如何处理异常)

调试Python程序时,经常会报出一些异常,异常的原因一方面可能是写程序时由于疏忽或者考虑不全造成了错误,这时就需要根据异常Traceback到出错点,进行分析改正;另一方面,有些异常是不可避免的,但我们可以对异常进行捕获处理,防止程序终止。

一、Python内置异常

Python的异常处理能力是很强大的,它有很多内置异常,可向用户准确反馈出错信息。

在Python中,异常也是对象,可对它进行操作。BaseException是所有内置异常的基类,但用户定义的类并不直接继承BaseException,所有的异常类都是从Exception继承,且都在exceptions模块中定义。

Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。

例如:如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。

内置异常类的层次结构如下:

二、requests模块的相关异常

要调用requests模块的内置异常,只要“from requests.exceptions import xxx”就可以了,比如:

from requests.exceptions import ConnectionError, ReadTimeout

或者直接这样也是可以的:

from requests import ConnectionError, ReadTimeout

requests模块内置异常类的层次结构如下:

下面是一个简单的小例子,python内置了一个ConnectionError异常,这里可以不用再从requests模块import了:

import requestsfrom requests import ReadTimeout def get_page(url): try: response = requests.get(url, timeout=1) if response.status_code == 200: return response.text else: print('Get Page Failed', response.status_code) return None except (ConnectionError, ReadTimeout): print('Crawling Failed', url) return None def main(): url = ' print(get_page(url)) if __name__ == '__main__': main()

三、用户自定义异常

此外,你也可以通过创建一个新的异常类拥有自己的异常,异常应该是通过直接或间接的方式继承自Exception类。下面创建了一个MyError类,基类为Exception,用于在异常触发时输出更多的信息。

在try语句块中,抛出用户自定义的异常后执行except部分,变量 e 是用于创建MyError类的实例。

class MyError(Exception): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg try: raise MyError('类型错误')except MyError as e: print('My exception occurred', e.msg)

except as e中的‘e’的作用:

这个e是异常类的一个实例,如果我们完整地解释这个问题,我觉得还是从Python的自定义异常类说起比较好。假如,我们现在自定义一个简单的异常类:

class MyError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value)

我们抛这个异常的时候可以这么写:

try: raise MyError(2*2)except MyError as e: print 'My exception occurred, value:', e.value

我们在捕获这个异常之后假如需要访问TA的一些属性怎么办,这个时候就可以使用as关键字所以,这里的e是前面MyError异常类的一个实例,我们可以直接访问他的value,也就是你看到的e.value

四、异常捕获

当发生异常时,我们就需要对异常进行捕获,然后进行相应的处理。python的异常捕获常用try…except…结构,把可能发生错误的语句放在try模块里,用except来处理异常,每一个try,都必须至少对应一个except。此外,与python异常相关的关键字主要有:

关键字

关键字说明

try/except

捕获异常并处理

pass

忽略异常

as

定义异常实例(except MyError as e)

else

如果try中的语句没有引发异常,则执行else中的语句

finally

无论是否出现异常,都执行的代码

raise

抛出/引发异常

1.捕获所有异常

包括键盘中断和程序退出请求(用sys.exit()就无法退出程序了,因为异常被捕获了),因此慎用。

try: <语句> except: print('异常说明')

2.捕获指定异常

try: <语句> except <异常名>: print('异常说明')

3.捕获万能异常:

try: <语句> except Exception: print('异常说明')

例如:

try: f = open("file-not-exists", "r") except IOError as e: print("open exception: %s: %s" %(e.errno, e.strerror))

4.捕获多个异常

捕获多个异常有两种方式,第一种是一个except同时处理多个异常,不区分优先级:

try: <语句> except (<异常名1>, <异常名2>, ...): print('异常说明')

第二种是区分优先级的:

try: <语句> except <异常名1>: print('异常说明1') except <异常名2>: print('异常说明2') except <异常名3>: print('异常说明3')

该种异常处理语法的规则是:

执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。

5.异常中的else

如果判断完没有某些异常之后还想做其他事,就可以使用下面这样的else语句。

try: <语句> except <异常名1>: print('异常说明1') except <异常名2>: print('异常说明2') else: <语句> # try语句中没有异常则执行此段代码

6.异常中的finally

try…finally…语句无论是否发生异常都将会执行最后的代码。

try: <语句> finally: <语句>看一个示例:str1 = 'hello world'try: int(str1)except IndexError as e: print(e)except KeyError as e: print(e)except ValueError as e: print(e)else: print('try内没有异常')finally: print('无论异常与否,都会执行我')

7.raise主动触发异常

可以使用raise语句自己触发异常,raise语法格式如下:

raise [Exception [, args [, traceback]]]

语句中Exception是异常的类型(例如ValueError),参数是一个异常参数值。该参数是可选的,如果不提供,异常的参数是"None"。最后一个参数是跟踪异常对象,也是可选的(在实践中很少使用)。

例如:

def not_zero(num): try: if num == 0: raise ValueError('参数错误') return num except Exception as e: print(e) not_zero(0)

五、 采用traceback模块查看异常

发生异常时,Python能“记住”引发的异常以及程序的当前状态。Python还维护着traceback(跟踪)对象,其中含有异常发生时与函数调用堆栈有关的信息。记住,异常可能在一系列嵌套较深的函数调用中引发。程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名。一旦异常被引发,Python会搜索一个相应的异常处理程序。如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止。这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(StackUnwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。

格式如下:

try: block except: traceback.print_exc()

例如:

try: 1/0except Exception as e: print(e)

如果我们这样写的话,程序只会报“division by zero”错误,但是我们并不知道是在哪个文件哪个函数哪一行出的错。

下面使用traceback模块,官方参考文档:​​traceback try: 1/0except Exception as e: traceback.print_exc()

这样就会帮我们追溯到出错点:

Traceback (most recent call last): File "E:/PycharmProjects/ProxyPool-master/proxypool/test.py", line 4, in 1/0ZeroDivisionError: division by zero

另外,traceback.print_exc()跟traceback.format_exc()有什么区别呢?

区别就是:format_exc()返回字符串,print_exc()则直接给打印出来。即traceback.print_exc()与print(traceback.format_exc())效果是一样的。

print_exc()还可以接受file参数直接写入到一个文件。比如可以像下面这样把相关信息写入到tb.txt文件去。

traceback.print_exc(file=open('tb.txt','w+'))

去期待陌生,去拥抱惊喜。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解决springboot项目打成jar包后运行时碰到的小坑
下一篇:运行Pytest命令行的选项参数【个人觉得很有帮助的一些参数】(pytest运行方式)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~