python学习笔记之异常(内置标准异常总结)

python异常处理机制

异常处理是python的一种高级工具,当异常发生时,程序会停止当前的所有工作,跳转到异常处理部分去执行。异常既可以是程序错误引发的,也可以由代码主动触发。

异常处理基本结构

try:
	可能引发异常的代码
except 异常类型名称:
	异常处理代码
else:
	没有发生异常时执行的代码

异常报错:

tryclass test:
		def getdata(self):
			return self.data
	y = test()
	y.getdata()
except AttributeError:
	print('出错了:访问对象属性出错')
else:
	print('程序中没有发生错误')
print('程序执行完毕!')

结果:

出错了:访问对象属性出错!
程序执行完毕

测试else部分执行

tryclass test:
		def getdata(self):
			return self.data
	y = test()
	y.data=100
	y.getdata()
except AttributeError:
	print('出错了:访问对象属性出错')
else:
	print('程序中没有发生错误')
print('程序执行完毕!')

结果:

程序中没有发生错误
程序执行完毕!

捕捉多个异常

在异常处理结构中,可以使用多个except语句,以捕捉可能出现的多种异常

x=[1,2]
try:
	x[0]/0
except ZeroDivisionError:
	print('除0错误')
except IndexError:
	print('索引下标超出范围')
else:
	print('没有错误')

结果:

0错误

引发不同异常

x=[1,2]
try:
	x[2]/2
except ZeroDivisionError:
	print('除0错误')
except IndexError:
	print('索引下标超出范围')
else:
	print('没有错误')

结果

索引下标超出范围

except…as与统一处理

x=[1,2]
try:
	x[0]/0
except (ZeroDivisionError,IndexError) as exp:
	print('出错了:')
	print('异常类型:',exp.__class__.__name__)
	print('异常信息:',exp)
else:
	print('没有错误')

结果

出错了:
异常类型:ZeroDivisionError
异常信息:division by zero

执行另一个异常

x=[1,2]
try:
	x[2]/2
except (ZeroDivisionError,IndexError) as exp:
	print('出错了:')
	print('异常类型:',exp.__class__.__name__)
	print('异常信息:',exp)
else:
	print('没有错误')

结果:

出错了:
异常类型:IndexError
异常信息:list index out of range

捕捉所有异常

在捕捉异常时,如果except语句中没有指明异常类型,则不管发生任何类型的异常,均会执行except语句块中的异常处理,采用这种方式好处是可以捕捉所有类型的异常,还可以进一步使用sys.exc_info()方法来获得详细的异常信息
sys.exc_info()方法返回一个三元组(type,value,traceobj),type为异常类的类型,用type.__name__属性可获得异常类名称。value为异常类的实例对象,直接打印可获得异常描述信息。traceobj是一个堆栈跟踪对象(traceback对象),使用traceback模块的print_tb()方法可获得堆栈跟踪信息

x=[1,2,3]
try:
	print(x[3])
except:
	import sys
	x=sys.exc_info()
	print('异常类型:%s'%x[0].__name__)
	print('异常描述:%s'%x[1])
	print('堆栈跟踪信息:')
	import traceback
	traceback.print_tb(x[2])

结果

异常类型:IndexError
异常描述:list index out of range
堆栈跟踪信息:
  File "<pyshell#200>", line 2, in <module>

异常处理结果的嵌套

python允许在异常处理结果的内部嵌套另一个异常处理结果,在发生异常时,内部没有捕捉处理的异常可以被外层捕捉

x=[1,2]
try:
    try:
        5/0
    except ZeroDivisionError:
        print('内部除0异常')
        x[2]/2
except IndexError:
    print('外层下标越界异常')

结果

内部除0异常
外层下标越界异常

try…finally终止行为

异常处理结构中,可以使用finally定义终止行为,不管try语句块中是否发生异常,finally语句模块中的代码都会执行

def dosome():
    try:
        print(5/0)
    except:
        print('出错了')
    finally:
        print('finally部分已执行')
    print('over')

dosome()

结果

出错了
finally部分已执行
over

主动引发异常

python允许在代码中使用raise或assert语句主动引发异常

raise语句

raise 异常类名			#创建异常类的实例对象,并引发异常
raise 异常类实例对象		#引发异常类实例对象对应的异常
raise					#重新引发刚刚的异常
用类名引发异常
>>>raise IndexError
Traceback (most recent call last):
  File "<pyshell#201>", line 1, in <module>
    raise IndexError
IndexError
用异常类实例对象引发异常
>>>x=IndexError()
>>>raise x
Traceback (most recent call last):
  File "<pyshell#203>", line 1, in <module>
    raise x
IndexError
传递异常
try:
    raise IndexError
except:
    print('出错了')
    raise

结果:

出错了
Traceback (most recent call last):
  File "<pyshell#205>", line 2, in <module>
    raise IndexError
IndexError
指定异常信息
>>>raise  IndexError('索引下标超出范围')
Traceback (most recent call last):
  File "<pyshell#206>", line 1, in <module>
    raise  IndexError('索引下标超出范围')
IndexError: 索引下标超出范围
异常链:异常引发异常

可以使用raise…from…语句,使用异常来引发另一个异常

>>>try:
    5/0
except Exception as x:
    raise IndexError('下标越界') from x

结果

Traceback (most recent call last):
  File "<pyshell#208>", line 2, in <module>
    5/0
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<pyshell#208>", line 4, in <module>
    raise IndexError('下标越界') from x
IndexError: 下标越界
assert语句
assert 测试表达式,data
>>>x=0
>>>assert x!=0,'变量x的值不能为0'
Traceback (most recent call last):
  File "<pyshell#210>", line 1, in <module>
    assert x!=0,'变量x的值不能为0'
AssertionError: 变量x的值不能为0

使用try来捕捉assert语句引发的AssertionError异常

try:
    import math
    x=-5
    assert x>=0,'参数x必须是非负数'
except Exception as ex:
    print('异常类型:',ex.__class__.__name__)
    print('异常信息:',ex)

结果

异常类型: AssertionError
异常信息: 参数x必须是非负数

自定义异常类

异常类超类

异常类的共同超类:BaseException和Exception

BaseException类

BaseException类是所有异常类的顶级超类,不能直接继承BaseException类来定义自己的异常类。BaseException唯一自雷是Exception类。BaseException类为子类提供了默认的打印和状态保持行为。在创建异常类实例对象时,可以用一个字符串作为异常描述信息。在打印异常类实例对象时,显示异常描述信息
实际上,在创建异常类实例对象时,可以提供多个参数,如果子类没有覆盖继承自己BaseException类的构造方法,所有的参数均会以元组的形式保存在args属性中

>>>x=IndexError(50,'下标越界')
>>>print(x)
(50,'下标越界')
>>>x.args
(50,'下标越界')
Exception类

Exception类是其他所有python内置异常类的超类,除了GeneratorExit、KeyboardInterrupt和SystemExit,通常用户自定义类均使用Exception类作为超类

try:
    5/0
except Exception as ex:
    print('异常类型:',ex.__class__.__name__)
    print('异常信息:',ex)
    print('堆栈跟踪信息:')
    import traceback
    traceback.print_tb(ex.__traceback__)

结果

异常类型: ZeroDivisionError
异常信息: division by zero
堆栈跟踪信息:
  File "<pyshell#214>", line 2, in <module>
创建自定义异常类
>>>class test(Exception):pass

>>>raise test('测试自定义异常类')
Traceback (most recent call last):
  File "<pyshell#220>", line 1, in <module>
    raise test('测试自定义异常类')
test: 测试自定义异常类
>>>
用自定义异常类保存异常日志
class myException(Exception):
    logfile='app_log_file.txt'
    def dolog(self):
        log = open(self.logfile,'a')
        from datetime import datetime
        x=datetime.today()
        print('\n出错了:',file=log)
        print('日期时间:',x,file=log)
        print('异常信息:',self.args[0],file=log)
        print('堆栈跟踪信息:',file=log)
        import traceback
        traceback.print_tb(self.args[1],file=log)
        log.close()
try:
    try:
        #raise myExceotion(''自定义异常类)
        print(5/0)
    except Exception as ex:
        raise  myException(ex.args[0],ex.__traceback__)
except myException as ex:
    ex.dolog()
finally:
    print('程序执行结束')

结果

程序执行结束

打开生成的文件内容显示:

出错了:
日期时间: 2020-03-03 16:46:09.709766
异常信息: division by zero
堆栈跟踪信息:
  File "F:/PycharmProjects/untitled/biji/2020.3.3.py", line 17, in <module>
    print(5/0)

***************************************************************************************************************************

Python标准异常总结

异常名作用
AssertionError断言语句(assert)失败
AttributeError尝试访问未知的对象属性
EOFError用户输入文件末尾标志EOF(Ctrl+d)
FloatingPointError浮点计算错误
GeneratorExitgenerator.close()方法被调用的时候
ImportError导入模块失败的时候
IndexError索引超出序列的范围
KeyError字典中查找一个不存在的关键字
KeyboardInterrupt用户输入中断键(Ctrl+c)
MemoryError内存溢出(可通过删除对象释放内存)
NameError尝试访问一个不存在的变量
NotImplementedError尚未实现的方法
OSError操作系统产生的异常(例如打开一个不存在的文件)
OverflowError数值运算超出最大限制
ReferenceError弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象
RuntimeError一般的运行时错误
StopIteration迭代器没有更多的值
SyntaxErrorPython的语法错误
IndentationError缩进错误
TabErrorTab和空格混合使用
SystemErrorPython编译器系统错误
SystemExitPython编译器进程被关闭
TypeError不同类型间的无效操作
UnboundLocalError访问一个未初始化的本地变量(NameError的子类)
UnicodeErrorUnicode相关的错误(ValueError的子类)
UnicodeEncodeErrorUnicode编码时的错误(UnicodeError的子类)
UnicodeDecodeErrorUnicode解码时的错误(UnicodeError的子类)
UnicodeTranslateErrorUnicode转换时的错误(UnicodeError的子类)
ValueError传入无效的参数
ZeroDivisionError除数为零

以下是python内置异常类的层次结构

BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
      +-- StopIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值