Day29 异常处理

有的错误是程序编写有问题造成的,比如本来应该输出整数结果输出了字符串,这种错误我们通常称之为bug,bug是必须修复的。

有的错误是用户输入造成的,比如让用户输入email地址,结果得到一个空字符串,这种错误可以通过检查用户输入来做相应的处理。

还有一类错误是完全无法在程序运行过程中预测的,比如写入文件的时候,磁盘满了,写不进去了,或者从网络抓取数据,网络突然断掉了。这类错误也称为异常,在程序中通常是必须处理的,否则,程序会因为各种问题终止并退出。

一、 异常

异常就是程序运行时发生的错误信号,在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止。

异常分为三部分:

  • 异常追踪信息
  • 异常类型
  • 异常值

错误

  • 语法错误:不符合语法规定,比如多缩进少缩进
  • 逻辑错误:语法正确,但也有如除于0这样的逻辑问题

常见异常类型

异常名称

描述

AttributeError

试图访问一个对象没有的属性

IOError

输入/输出异常;基本上是无法打开文件

ImportError

无法引入模块或包;基本上是路径问题或名称错误

IndentationError

语法错误(的子类);代码没有正确对齐

IndexError

下标索引超出序列边界,试图访问不存在的索引

KeyError

试图访问字典中不存在的键

KeyboardInterrupt

用户按下了 Ctrl+C 键中断程序执行

NameError

使用一个还未被赋值的变量

SyntaxError

Python代码非法,代码不能编译,通常是语法错误

TypeError

传入对象类型与要求的类型不符

UnboundLocalError

试图访问一个还未被设置的局部变量,由于存在同名的全局变量导致混淆

ValueError

传入一个调用者不期望的值,即使值的类型是正确的

为了保证程序的健壮性和可读性,必须对异常进行处理

if-else循环语句同样可以进行异常处理,但往往异常是未知的、复杂的,使用try-except则更为合理

try:
    被检测的代码块
except 异常类型:
    try中一旦检测到异常,就执行这个位置的逻辑
else:
    如果没发生错误,自动执行else语句
finally:
    有finally语句,则一定会被执行(可以没有)

try...except可以跨越多层调用捕获到错误,如果在一个函数中调用其他函数,其他函数又调用另外的函数,即使这个另外的函数出错,依然可以捕获到并处理。不需要在每个可能出错的地方去捕获错误,只需要在合适的层次写好try...except即可。

出错的时候,一定要分析错误的调用栈信息,才定位错误的位置。

1.多分支结构

可能出现不同异常,对于不同异常进行不同的处理

s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
except Exception as e:	# Exception则为万能异常
    print(e)

2.其他结构

s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
#except Exception as e:
#    print(e)
else:
    print('try内代码块没有异常则执行我')
finally:
    print('无论异常与否,都会执行该模块,通常是进行清理工作')

3.自定义异常

Python所有错误都是从BaseException类派生的,常见的错误类型和继承关系有:

Built-in Exceptions — Python 3.11.4 documentation

class EgonException(BaseException):	# 必须继承BaseException类
    def __init__(self,msg):
        self.msg=msg

try:
    raise EgonException('类型错误')	# 主动触发异常
except EgonException as e:
    print(e)

只有在有必要的时候才定义我们自己的错误类型。如果可以选择Python已有的内置错误类型,尽量使用Python内置的错误类型。

raise语句如果不带参数,就会把当前错误原样抛出。在except中raise一个Error,可以把一种类型的错误转化为另一种类型(只要是合理的转换逻辑)。

try:
    10 / 0
except ZeroDivisionError:
    raise ValueError('input error!')

4.断言

语法:assert condition, message

  • condition是需要检查的条件,如果条件为假,则引发AssertionError异常;
  • message是可选的错误消息,用于在断言失败时提供更具体的说明

断言可用于验证代码中的假设和预期条件是否满足。通过在关键位置插入断言语句,可以快速检测到错误并确定错误的原因

需要注意的是,断言语句在生产环境中通常应该被禁用,因为它们会增加运行时的开销。可以通过设置Python解释器的优化级别来禁用断言。也可以通过在启动Python解释器时用-O(大写字母O,不是数字0)参数来关闭assert,关闭后,所有的assert语句都当作pass。

在开发和调试阶段,可以启用断言来帮助捕获和修复问题,而在生产环境中应该关闭断言以提高性能

总结

try-except

  1. 把错误处理和真正的工作分开来
  2. 代码更易组织,更清晰,复杂的工作任务更容易实现
  3. 毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了

异常处理是保底的,只是在错误发生的条件无法预知时,才应该使用,过多的异常处理也会增加开销,降低代码可读性

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值