Python 错误和异常 概念

2022-08-21 13:18:58

异常多指程序在执行的过程中,出现的未知错误,语法和逻辑都是正确的,可以通过其他代码进行处理修复。
错误指没法通过其他的代码进行处理的问题。

常见的系统异常

  • 除零异常 ZeroDivisionError
  • 名称异常 NameError
  • 类型异常 TypeError
  • 索引异常 IndexError
  • 键异常 KeyError
  • 值异常 ValueError
  • 属性异常 AttributeError
  • 迭代器异常 StopIteration

系统异常类继承树

BaseException 所有内建的异常的基类

  • SystemExit 由sys.exit()函数引发。当它不处理时,python 解释器退出
  • KeyboardInterrupt 当用户点击中断键(ctrl + C)时引发
  • GeneratorExit 当调用一种generator的close()方法时引发
  • Exception 所有的内置的,非系统退出异常是从该类派生。应该从该类派生所有用户定义的异常
try:print(name)except NameError:print('名称有问题')

try:
可能会出现异常的代码,这里不管以后会抛出多少个异常,只会从上往下检测,检测到一个后,就会立即往下去匹配,不会多次检测。

try:1/0print(name)except ZeroDivisionError:print('除零异常')except NameError:print('名称有问题')else:print('不出现异常执行')finally:print('最后执行的内容,到时候,不管是否会出现异常,都会执行的语句')

except 你要捕捉的异常类型 as 接收异常的形参:
可以有多个重复,用于捕捉可能的其他异常

try:# 1 / 0print(name)except ZeroDivisionErroras ze:print('除零异常', ze)except NameErroras ne:print('名称有问题', ne)

名称有问题 name ‘name’ is not defined

else:
没出现异常时做的处理,这一块必须放在上一块 except 结束后。

finally:
不管有没有出现异常,都会执行的代码,这一块必须放在最后

try:# 1 / 0print(name)except(ZeroDivisionError, NameError)as e:print('xxx', e)

xxx name ‘name’ is not defined

异常名称不确定,而又想捕捉,可以直接写exception

try:# 1 / 0print(name)except Exceptionas e:print('xxx', e)

xxx name ‘name’ is not defined

with context_expression[as tearet(s)]

适用于执行某一段代码A之前,进行预处理,执行代码A结束后,进行清理操作。不管出现了什么异常,最终都要执行一些清理操作。

withopen('xxx.jpg','r')as f:
    f.readlines()

自定义上下文管理器

classTest:def__enter__(self):print('enter')return selfdef__exit__(self, exc_type, exc_val, exc_tb):print(self, exc_type, exc_val, exc_tb)print('exit')with Test()as x:print('body', x)

enter
body <main.Test object at 0x0000020E4AD59B88>
<main.Test object at 0x0000020E4AD59B88> None None None
exit

import tracebackclassTest:def__enter__(self):print('enter')return selfdef__exit__(self, exc_type, exc_val, exc_tb):print(self, exc_type, exc_val, exc_tb)print(traceback.extract_tb(exc_tb))print('exit')returnTruewith Test()as x:# print('body', x)1/0

enter
<main.Test object at 0x000002AD16F08BC8> <class ‘ZeroDivisionError’> division by zero <traceback object at 0x000002AD16F1CC08>
[<FrameSummary file d:\python\python_learn\test.py, line 16 in >]
exit

contextlib 模块

@contextlib.contextmanger 使用装饰器,让一个生成器变成一个上下文管理器

import contextlib

@contextlib.contextmanagerdeftest():"""
    docstring
    """print(1)yield'xxx'print(2)with test()as x:print(3, x)

1
3 xxx
2

import contextlib

@contextlib.contextmanagerdefze():try:yieldexcept ZeroDivisionErroras e:print('error', e)

x=1
y=0with ze():
    x/ y

error division by zero

contextlib.closing

这个函数,让一个拥有close方法但不是上下文管理器的对象变成上下文管理器

import contextlibclassTest:deft(self):print('ttt')defclose(self):print('资源释放')with contextlib.closing(Test())as t_obj:
    t_obj.t()

ttt
资源释放

withopen('xx.jpg','rb')as from_file,open('xx2.jpg','wb')as to_file:
    from_contents= from_file.read()
    to_file.write(from_contents)

手动抛出异常

通过raise语句直接抛出相关类型的异常

defset_age(age):if age<=0or age>200:raise ValueError('值错误')else:print(age)

set_age(-18)
classLessZero(Exception):def__init__(self, msg)->None:
        self.msg= msgdef__str__(self)->str:return'123'defset_age(age):if age<=0or age>200:raise LessZero('值错误')else:print(age)

set_age(-18)
classLessZero(Exception):def__init__(self, msg, error_code)->None:
        self.msg= msg
        self.ec= error_codedef__str__(self)->str:return self.msg+str(self.ec)defset_age(age):if age<=0or age>200:raise LessZero('小于0值错误',404)else:print(age)try:
    set_age(-18)except LessZeroas e:print('x', e)

x 小于0值错误404

  • 作者:core571
  • 原文链接:https://blog.csdn.net/core571/article/details/108782934
    更新时间:2022-08-21 13:18:58