Python 错误和异常 概念

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

常见的系统异常

  • 除零异常 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 / 0
    print(name)
except ZeroDivisionError:
    print('除零异常')
except NameError:
    print('名称有问题') 
else:
    print('不出现异常执行')
finally:
    print('最后执行的内容,到时候,不管是否会出现异常,都会执行的语句')

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

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

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

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

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

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

xxx name ‘name’ is not defined

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

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

xxx name ‘name’ is not defined

with context_expression[as tearet(s)]

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

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

自定义上下文管理器

class Test:
    def __enter__(self):
        print('enter')
        return self
    
    def __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 traceback

class Test:
    def __enter__(self):
        print('enter')
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(self, exc_type, exc_val, exc_tb)
        print(traceback.extract_tb(exc_tb))
        print('exit')
        return True

with 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.contextmanager
def test():
    """
    docstring
    """
    print(1)
    yield 'xxx'
    print(2)

with test() as x:
    print(3, x)

1
3 xxx
2

import contextlib

@contextlib.contextmanager
def ze():
    try:
        yield
    except ZeroDivisionError as e:
        print('error', e)

x = 1
y = 0

with ze():
    x / y

error division by zero

contextlib.closing

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

import contextlib

class Test:
    def t(self):
        print('ttt')
    
    def close(self):
        print('资源释放')

with contextlib.closing(Test()) as t_obj:
    t_obj.t()

ttt
资源释放

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

手动抛出异常

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

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

set_age(-18)
class LessZero(Exception):
    def __init__(self, msg) -> None:
        self.msg = msg
    
    def __str__(self) -> str:
        return '123'



def set_age(age):
    if age <= 0 or age > 200:
        raise LessZero('值错误')
    else:
        print(age)

set_age(-18)

class LessZero(Exception):
    def __init__(self, msg, error_code) -> None:
        self.msg = msg
        self.ec = error_code
    
    def __str__(self) -> str:
        return self.msg + str(self.ec)



def set_age(age):
    if age <= 0 or age > 200:
        raise LessZero('小于0值错误', 404)
    else:
        print(age)

try:
    set_age(-18)
except LessZero as e:
    print('x', e)

x 小于0值错误404

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值