龙空技术网

python的异常机制

bwdi 196

前言:

如今小伙伴们对“python 警告忽略”大致比较关怀,咱们都想要了解一些“python 警告忽略”的相关内容。那么小编在网上汇集了一些有关“python 警告忽略””的相关资讯,希望你们能喜欢,姐妹们一起来了解一下吧!

在编写程序的时候,有时候会遇到程序异常的情况。譬如对0进行整除,我们可以对每个运算都进行条件判断,然而这种做法效率低且灵活性很差,使得代码冗杂,生涩难读。这时候,可以用python提供的「异常处理机制」。

1 异常是什么

在介绍这个机制之前,先必须明了,异常是什么?

在自然语言中,「异常」是正常情况以外的情异常况,具有不确定性。python使用异常对象来表示异常状态,每个异常都是某个异常类的实例,这一点和java类似。

2如何自主地抛出异常

通常,当我们写的程序出现不可预测的问题时,都会自动引发异常。那么如何自主地抛出异常呢?

要引发异常使用的是raise语句,并将一个Exception类或者他的子类作为参数。例如:

>>> raise Exception('这里写提示信息')Traceback (most recent call last): File "<stdin>", line 1, in <module>Exception: 这里写提示信息

在java中所有的异常类的祖先类都是Exception,这一点python也几乎是一样的。

python内置了一些异常类,他们都可以作为raise语句的参数。

类名:描述Exception :几乎所有的异常类都是她的子类AttributeError:引用属性或者给他赋值的时候失败OSError:操作系统无法执行指定的任务IndexError:访问序列中不存在的索引KeyErro:使用映射中不存在的KeyNameError:找不到变量的名称SyntaxError:代码不正确TypeError:将内置操作或者函数用于类型不正确的对象ValueError:内置操作或者函数的对象类型正确但值错误

以上只是一些常用的内置异常。

3 如何自定义异常类

虽然内置异常的涉及范围很广,但有时我们想使用自己的异常类。如何自定义异常类?

异常类必须直接或者间接继承Exception,例如:

>>> class MyException(Exception): pass
4捕获异常

异常捕获一般使用try/exception语句,例如:

try:	x=int(input('input N'))	if (x==0): raise Exception	y=np.log(x)except Exception:	print('N can not be zero')exception … :	…

异常从函数的内部向外部传播,如果在函数内不捕获,在调用函数的地方也可以捕获。但如果在函数内捕获了,外部就无法捕获了。

当我们在函数内捕获了异常,并且还想让他继续传播到调用函数的地方,可以在捕获的时候调用raise,例如:

>>> try:... 1/0... except ZeroDivisionError:... raise... Traceback (most recent call last): File "<stdin>", line 2, in <module>ZeroDivisionError: division by zero

当给raise加上参数的时候,发生了:

>>> try:... 1/0... except ZeroDivisionError:... raise ValueError... Traceback (most recent call last): File "<stdin>", line 2, in <module>ZeroDivisionError: division by zeroDuring handling of the above exception, another exception occurred:Traceback (most recent call last): File "<stdin>", line 4, in <module>ValueError

正如解释器所说的,在处理当前异常的时候,另一个异常也被捕获了。这是因为1/0引发的ZeroDivisionError异常被当作ValueError异常的上下文存储起来了。

可以使用语句 raise … from … 来自己提供异常上下文,例如:

>>> try:... 1/0... except ZeroDivisionError:... raise ValueError from TypeError... TypeErrorThe above exception was the direct cause of the following exception:Traceback (most recent call last): File "<stdin>", line 4, in <module>ValueError

根据提示信息可知,‘from’后的 异常是‘raise’后的异常的直接原因。

当使用‘raise … from None’时,可以消除上下文的关联。

在上面的一个例子中,曾经给出了多个except语句来捕获不同的异常,例如:

try:	…except ZeroDivisionError:	…except ValueError:	…

当我们想要用一个excep语句捕获多个异常的时候,可以在一个元组中指定这些异常,例如:

try:	…except (ZeroDivisionError,… ):	…
5捕获对象

当我们想要访问异常的对象的时候,可以在异常类后面增加一个参数,例如:

>>> try:... 'x'/0... except (ZeroDivisionError,TypeError) as e:... print(e)... unsupported operand type(s) for /: 'str' and 'int'

可以看到,上述的式子出发了两个异常,但最终捕获的只有一个,这是因为异常机制只捕获最近产生的异常,Traceback (most recent call last)。

6当没有出现异常的时候

在有些情况下,我们不会出发任何异常,这样就可以仿照条件语句,添加一个else语句:

>>> try:... x=1/2... except:... print("exception occured")... else:... print("万事大吉")... 万事大吉
7finally

我想在设计外卖平台的时候的时候,一个点单行为一般会先产生一个订单,然后跳转到支付界面,当用户完成支付,商家确认之后,这条订单才算真正完成。

然而,在订单产生之后的各个环节都有可能出现异常,譬如用户没有支付或者支付失败。这时候就可以用final语句,来删除这条订单。

finally子句可以用于发生异常时执行清理工作,它可以捕获所有的异常。

譬如上面的例子:

try:	一个订单X产生	支付	商家确认finally:	删除订单

上面这个例子是我现编的,不知道真实的公司会不会这么草率地删除一项记录。

不过finally真的非常适合用于确保文件或者网络套接字等关掉。

8警告

编程的时候会遇到一些警告,警告类似于异常。但他们通常都是只打印一条错误消息。

例如:

>>> import warnings as win>>> win.warn("this is a warning")__main__:1: UserWarning: this is a warning>>> win.warn("this is second warning")__main__:1: UserWarning: this is second warning>>> win.warn("this is a warning")

警告只显示一次,如果再次运行一次win.warn("this is a warning"),是不会显示警告内容的。

每当生成一个警告时,都需要将其与注册过的过滤器比较,第一个匹配的过滤器将控制这个警告采取的动作,否则采取默认的动作,其实本质流程上会发现与Exception异常处理类似,看一下常见的过滤器动作:

 error:将警告提升为异常 ignore:忽略警告 always:总是抛出警告 default:从各个位置第一次生成警告时输出警告 module:从各个模块第一次生成警告时输出警告 once:第一次生成警告时输出警告

有时候的一些警告没有什么特殊的意义,我们可以使用函数将他们抑制,例如:

>>> win.filterwarnings("ignore")>>> win.warn("this is second warning ")>>> win.warn("this is second warning ")Traceback (most recent call last): File "<stdin>", line 1, in <module>UserWarning: this is second warning 

上面分别展示了ignore和error两种状况,分别将警告忽略或者转成错误。

一般而言,一个警告只出现一次,但是使用always可以让他每次执行都出现,

>>> win.warn("this is third warning",)__main__:1: UserWarning: this is third warning>>> win.warn("this is third warning",)__main__:1: UserWarning: this is third warning

标签: #python 警告忽略