Python学习笔记——错误和异常

错误的分类

编写程序过程中遇到的错误都分为两类:语法错误与运行时错误。

语法错误:当代码不符合Python语法规则时, 在解析过程中会报SyntaxError。

运行时错误:即语句或表达式在语法上都是正确的, 但在运行时发生了错误。

当程序发生异常时,默认会终止程序的。可以通过使用捕获异常的方式获取异常名称,并通过代码逻辑让程序继续执行,这种逻辑叫做异常处理。

异常的基本语法

异常语法的定义:

try:
    〈语句〉             #运行别的代码
except  <名字〉:
    〈语句〉
except  <名字〉,〈数据〉:
    〈语句〉                #如果引发了’name’异常, 获得附加的数据
else:
    〈语句〉                #如采没有异常发生, 则执行该分支语句

except关键字还可以同时接收多个异常具体的写法是在except后面加个括号, 将要接收的异常当作参数传入。

try:
    x = int(input('请入一个被除数:'))        #等待输入一个数, 并赋位给x
    print('30除以', x, '等于', 30/x)         #输出30以x
except(ZeroDivisionError,ValueError):        #同时捕获ZeroDivisionError与ValueError异常
    print('输入错误, 重新输入……')
except:                                      #捕获其他异常
    print('其他异常……')
try……except...…语句后面还可以跟else语句。当没有异常发生时, 将执行else语句。else语句是个可选语旬, 必须要放在所有except语句后面。

捕获异常类型:通过except后面跟着Exception as e的语旬, 可得到异常类型e。

输出异常详细信息

捕获异常时, 可以使用sys模块中的exc_info函数, 或使用traceback模块中的相关函数, 来获得更多的异常信息。详细介绍如下:

1、 sys的exc_info函数

模块sys中有两个函数可以返回异常的全部信息:一个是exc_info;另一个是last_traceback。两个函数有相同的用法及功能。

exc_info函数会将当前的异常信息以元组的类型返回。元组内包含3个元素, 分别为type、value和traceback。

  • Type:异常类型的名称, 它是BaseException的子类

  • value:捕获到的异常实例

  • traceback:是一个traceback对象

import sys
try:
    x = int(input('请输入一个被除数:'))
    print('30除以', x, '等于', 30/x)
except:
    print(sys.exc_info())  
#(<class 'ZeroDivisionError' >,  ZeroDivisionError ('division by zero ',) , <traceback
#object at Ox000000000C745748 >)
    print('其他异常……')

输出结果的第2行为异常的全部信息。该信息是一个元组类型。元组的第1个元素是一个ZeroDivisionError类:第2个元素是异常类型ZeroDivisionError类的一个实例;第3个元素为一个traceback对象。

2、 traceback对象的显示

要查看traceback对象的内容, 需要先引入traceback模块, 调用traceback模块中的print_tb方法, 并将sys.exc_info输出的traceback对象传入。print_tb方法专用于显示traceback对象的内容。

import traceback
import sys
try:
    x = int(input('请输入一个被除数:'))
    print('30除以', x, '等于', 30/x)
except:
    traceback.print_tb(sys.exc_info()[2])       #打印traceback对象
    print('其他异常……')
else:
    print("再见")

3、 traceback模块的其它函数

通过traceback模块的载入, 可以更简单地获得更多异常信息显示。比如调用traceback对象的print_exc方法, 可以直接将异常内容打印出来。

在traceback模块中, 还有功能类似的print_exception函数。但是print_exception要传入sys.exc_info()的结果。

# 下面两行代码等价
traceback.print_exc()
traceback.print_exception(*sys.exc_info())

捕获预处理异常

try语句在执行时, 如果出现了一个异常, 该语句的剩余部分将被跳过;如果该异常的类型匹配到了except后面的异常名, 则该except后的语句将被执行。

注意:如果except后面没有跟异常名, 必须放在所有捕获异常的语句之后, 表示它可以匹配任何类型的异常。

try语句的工作原理:

(1)当执行一个try语句后, Python就在当前程序的上下文中做标记。

(2)如果程序出现异常, 系统就会回到标记处。接着执行第一个匹配该异常的except子句。异常处理完毕, 控制流就跳过整个try语句(除非在处理异常时又引发新的异常)。

(3)如果程序出现异常, 但没有找到相匹配的except子句。异常将被递交到上层的try或者程序的最上层(这样将结束程序, 并打印默认的出错信息)。

(4)如果try子句在执行时没有发生异常, Python将执行else的语句(如果有else的话), 然后控制流跳过整个try语句。

常见异常

创建异常

创建异常又叫抛出异常, 也叫作触发异常, 是主动向系统报出异常, 使用关键宇raise来实现。

语法:raise [ Exception [ , args [ , traceback ] ] ]

  • Exception:异常参数值, 指代常的类型(例如, NameError)。该参数是可选的, 默认是None。

  • traceback:是可选的(在实践中很少使用), 代表所要跟踪的异常对象。

注意:raise抛出的异常必须是一个异常实例或类(派生自Exception的类)。

try:
    x = int(input('请输入一个被除数:'))
    if 0 == x:
        raise ValueError('输入错误:不能做被除数')
    print('30除以', x, '等于', 30/x)
except Exception as e:
    print(e)
except ZeroDivisionError:
    print('被除数不等于0, 重新输入......')
except 
    print('其他异常……')

异常的最终处理

Python中, finally语句是与町和except语句配合使用的。

finally语句中的内容般都是用来做清理工作的。无论try中的语句是否跳入except中, 最终都要进入finally语句, 并执行finally语句的分支代码。

finally与else的区别:

  • else语句只在没有异常发生的情况下执行。

  • finally语句则不管异常发生与否都会执行。

finally语句总是在退出try语句前被执行, 无论是正常退出、异常退出, 还是通过break、continue、return语句退出。

断言

断言,使用assert关键宇后面接着一个条件表达式。如果条件表达式为真, 意味着程序当前的条件与开发人员自己断言的情况一致, 则程序继续行;如果为假, 则表明一定是前面发生了错误, 程序停止运行, 报出异常。

Python中, 如果断言后面的条件语句失败了, 还可以为其指定对应的字符串输出。具体做法是:直接在assert后面的条件语句之后, 加上“字符串”

assert 1 != 1,("1不等于1, 报错")     #断言1不等于1

自定义异常

通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承

>>> 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)
   
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值