20210225-1 Python错误与异常「建议收藏」

20210225-1 Python错误与异常「建议收藏」一、什么是异常Python错误与异常什么是异常>异常是一个事件,该事件会在程序执行过程中发生,影响程序的正常执行。一般情况下,在Python无法正常处理程序时就会发生异常。异常是Pyth

大家好,又见面了,我是你们的朋友全栈君。

 

一、什么是异常

 

Python错误与异常

什么是异常

> 异常是一个事件,该事件会在程序执行过程中发生,影响程序的正常执行。一般情况下,在Python无法正常处理程序时就会发生异常。异常是Python的对象,表示一个错误。当Python脚本发生异常时,我们需要捕获并处理异常,否则程序会终止执行。

> 每一个异常都是一些类的实例,这些实例可以被引用,并且可以用很多种方法进行捕捉,使得错误可以被处理,而不是让整个程序失败。

代码里会有很多异常,比如 NameError 名称错误,Syntax Error 语法异常,Type Error 类型错误,Value Error值异常;这四种都是异常,异常其实是一个事件

代码里有异常是非常正常的事情,捕获到异常,扔掉就可以了

>>> 10*(1/0)

Traceback (most recent call last):

File “<stdin>”, line 1, in <module>

ZeroDivisionError: division by zero

>>> 4+a1*3

Traceback (most recent call last):

File “<stdin>”, line 1, in <module>

NameError: name ‘a1’ is not defined

>>> ‘2’+2

Traceback (most recent call last):

File “<stdin>”, line 1, in <module>

TypeError: can only concatenate str (not “int”) to str

这些就叫做异常

 

二、异常处理

 

异常处理

> try语句的基本形式为try/except。try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。如果你不想在发生异常时结束程序,只需在try语句块中捕获异常即可。

> 捕获异常的语法如下:

> 异常捕捉try/except

20210225-1 Python错误与异常「建议收藏」

1-1
def exp_exception(x,y): try: a=x/y print('a=',a) return a except Exception: print("程序出现异常,异常信息:被除数为0") exp_exception(2,2) => a= 1.0
1-2
def exp_exception(x,y): try: a=x/y print('a=',a) return a except Exception: print("程序出现异常,异常信息:被除数为0") exp_exception(2,0) => 程序出现异常,异常信息:被除数为0

 

> 捕捉多个异常

20210225-1 Python错误与异常「建议收藏」

1-1
def exp_exception(x,y): try: a=x/y b=name print('a=',a) return a except ZeroDivisionError: print("除数不能为0") except NameError: print("没有你要找的名字") exp_exception(2,0) => 除数不能为0
1-2
def exp_exception(x,y): try: a=x/y b=name print('a=',a) return a except ZeroDivisionError: print("除数不能为0") except NameError: print("没有你要找的名字") exp_exception(2,2) => 没有你要找的名字

 

> 使用一个块捕捉多个异常

> 如果需要使用一个块捕捉多个类型异常,可以将它们作为元组列出。使用该方式时,遇到的异常类型是元组中的任意一个,都会走异常流程。

> 这么做有什么好处呢?假如我们希望多个except子句输出同样的信息,就没有必要在几个except子句中重复输入语句,放到一个异常块中即可。

刚刚使用 except 捕获了两个异常,现在想把两个异常写到一个except中

def exp_exception(x,y): try: a=x/y b=name print('a=',a) return a except (ZeroDivisionError,NameError,TypeError): print("你的输出数据有误!") exp_exception(2,'0') => 你的输出数据有误!

 

异常处理

> 捕捉对象

> 如果希望在except子句中访问异常对象本身,也就是看到一个异常对象真正的异常信息,而不是输出自己定义的异常信息,可以使用as e的形式,我们称之为捕捉对象。

def exp_exception(x,y):
    try:
        a=x/y
        b=name
        print('a=',a)
        return a
    except (ZeroDivisionError,NameError,TypeError) as e:
        print(e)    # 输出 e,这地方不要写自己自定义的内容
 
exp_exception(2,'0')
exp_exception(2,0)
exp_exception(2,2)
=>
unsupported operand type(s) for /: 'int' and 'str'
division by zero
name 'name' is not defined

这就是捕捉对象,前面的异常提示是自定义的,捕捉对象的意思是系统给的系统提示,用 as e 即可

用系统给出的提示相比更便于定位

 

> 全捕捉

> 在实际编码过程中,即使程序能处理好几种类型的异常,但有一些异常还是会从我们手掌中溜走。对于这种情况我们根本无法预测会发生什么,也无法提前做任何准备。在这种情况下,与其使用不是捕捉异常的try/except语句隐藏异常,不如让程序立即崩溃。

def exp_exception(x,y):
    try:
        a=x/y
        b=name
    except (ZeroDivisionError,NameError,TypeError) as e:
        print(e)   
 
exp_exception(2,'')
=>
unsupported operand type(s) for /: 'int' and 'str'

这样b=name的异常就逃走了,没有对 b 进行检查

对于这种情况,无法预测未来会发生什么,也没办法提前做任何准备,所以缺陷一定会产生,所以这时不如让异常直接崩溃,直接在后面什么都不写就可以了

def exp_exception(x,y):
    try:
        a=x/y
        b=name
    except:
        print("Error")   
 
exp_exception(2,'')
=>
Error

后面什么都不写就叫全捕捉,当然这只是一种解决方案,从实用性角度看不建议这样做,因为这样捕捉异常非常危险,会隐藏所有没有预先想到的错误

 

> try/except…else

> try/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后。

> else 子句将在 try 子句没有发生任何异常的时候执行。

> try/except…else

20210225-1 Python错误与异常「建议收藏」

def exp_exception(x,y):
    try:
        a=x/y
    except:
        print("Error")   
    else:
        print("程序没有错误,执行结束")
 
exp_exception(2,'')
exp_exception(2,2)
=>
Error

程序没有错误,执行结束

当程序没有异常时,会执行 else 子句流程

 

> try-finally 语句

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

> 在有finally的异常处理程序中,finally中的子句一定是最后执行的。finally子句在关闭文件或数据库连接时非常有用

20210225-1 Python错误与异常「建议收藏」

如果有异常,try => except => finally

如果无异常,try => else => finally

def use_finally(x,y):
    try:
        a=x/y
    finally:
        print("不管有没有异常,都会执行我的哦~")
 
use_finally(2,2)
use_finally(2,0)
=>
不管有没有异常,都会执行我的哦~
不管有没有异常,都会执行我的哦~
Traceback (most recent call last):
 File "d:/VSCode/Untitled-1.py", line 10, in <module>
 use_finally(2,0)
 File "d:/VSCode/Untitled-1.py", line 5, in use_finally
 a=x/y
ZeroDivisionError: division by zero

但这引起了一个新的问题,虽然执行了 finally 语句,但是还是抛出异常了

能不能用 except 在 try 里面解惑它呢

def use_finally(x,y):
    try:
        a=x/y
    except ZeroDivisionError:
        print("除数不能为0")
    finally:
        print("不管有没有异常,都会执行我的哦~")
 
use_finally(2,2)
use_finally(2,0)
=>
不管有没有异常,都会执行我的哦~
除数不能为0
不管有没有异常,都会执行我的哦~

现在加上else也是一样可以的

def use_finally(x,y):
    try:
        a=x/y
    except ZeroDivisionError:
        print("除数不能为0")
    else:
        print("程序执行成功")
    finally:
        print("不管有没有异常,都会执行我的哦~")
 
use_finally(2,2)
use_finally(2,0)
=>
程序执行成功
不管有没有异常,都会执行我的哦~
除数不能为0
不管有没有异常,都会执行我的哦~

除了 try,后面的 except else 和 finally 都被称为 try 的子句,必须和 try 配合使用才有意义

 

三、抛出异常

 

抛出异常

> Python 使用 raise 语句抛出一个指定的异常。

> raise语法格式如下:

20210225-1 Python错误与异常「建议收藏」

前面一直在说捕获异常,异常必须是能够抛出来才能捕获的,python中使用 raise 抛出指定的异常

使用 raise 触发异常,把异常引出来即可,用实例调用 raise 语句,引发异常

>>> raise Exception

Traceback (most recent call last):

File “<stdin>”, line 1, in <module>

Exception

>>> raise NameError(“This is NameError”)

Traceback (most recent call last):

File “<stdin>”, line 1, in <module>

NameError: This is NameError

通过 这两个实例,可以看出,第一个实例引发没有相关错误信息的普通异常

第二个输出了一些错误提示;

如果只想知道有没有抛出异常,并不想处理它,使用一个 raise 就可以把异常抛出

try:
    raise NameError("这是一个NameError")
except NameError:
    print("捕捉到NameError") # 不加 raise,输出对应字符就结束
=>
捕捉到NameError
try:
    raise NameError("这是一个NameError")
except NameError:
    print("捕捉到NameError")
    raise
=>
捕捉到NameError
Traceback (most recent call last):
 File "d:/VSCode/Untitled-1.py", line 4, in <module>
 raise NameError("这是一个NameError")
NameError: 这是一个NameError

这样又把 NameError异常抛出来了,raise可以抛出更深更详尽的异常信息

 

Python重要的内建异常类

Exception:常规错误的基类

AttributeError:对象没有这个属性

IOError:输入/输出操作失败

IndexError:序列中没有此索引

KeyError:映射中没有这个键

NameError:未声明/初始化对象(没有属性)

SyntaxError:python语法错误

SystemError:一般解释器系统错误

ValueError:传入无效的参数

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/156008.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • excel 堆积折线图_什么叫堆积折线图

    excel 堆积折线图_什么叫堆积折线图excel中关于折线图和堆积折现图的解释:“堆积折线图和带数据标记的堆积折线图堆积折线图用于显示每一数值所占大小随时间或有序类别而变化的趋势,可能显示数据点以表示单个数据值,也可能不显示这些数据点。如果有很多类别或者数值是近似的,则应该使用无数据点堆积折线图。提示为更好地显示此类型的数据,您可能要考虑改用堆积面积图。更通俗的解释为: 如果有两个数据系列,折线图中两个数据系列是独立…

  • java绘图板

    java绘图板

  • hdu 4691 最长的共同前缀 后缀数组 +lcp+rmq

    hdu 4691 最长的共同前缀 后缀数组 +lcp+rmq

  • Pytest(6)重复运行用例pytest-repeat[通俗易懂]

    Pytest(6)重复运行用例pytest-repeat[通俗易懂]前言平常在做功能测试的时候,经常会遇到某个模块不稳定,偶然会出现一些bug,对于这种问题我们会针对此用例反复执行多次,最终复现出问题来。自动化运行用例时候,也会出现偶然的bug,可以针对单个用例,

  • c ringbuffer 源码_ringbuffer.c

    c ringbuffer 源码_ringbuffer.c#include#include#include#include#include”ringbuffer.h”/*createanewringbuffer*@capacitymaxbuffersizeoftheringbuffer*@returntheaddressofthenewringbuffer,NULLforerror.*/RING_BUF…

  • 104规约使用总结(一)——格式介绍

    104规约使用总结(一)——格式介绍一、格式APDU应用规约数据单元(整个数据)=APCI应用规约控制信息(固定6个字节)+ASDU应用服务数据单元(长度可变)二、固定帧报文1、格式常见帧:启动数据传输激活:680407000000(U帧)启动数据传输确认:68040B000000(U帧)测…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号