Python 笔记 — 异常

本文介绍了Python中异常的概念,列举了常见的异常类型,如AttributeError、IOError等,并详细讲解了异常的捕获、完整捕获、传递和主动抛出的方法,强调了异常处理在程序稳定性和健壮性中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概念

就是程序运行时发生错误的信号
当 Python 检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"。

二、常见种类

1、AttributeError

试图访问一个对象没有的属性,比如 test.x,但是 test 没有属性 x。

2、IOError

输入或输出异常,基本上是无法打开文件。

3、ImportError

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

4、IndentationError

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

5、IndexError

下标索引超出序列边界,比如当 x 只有三个元素,却试图访问 x[5]。

6、KeyError

试图访问字典里不存在的键。

7、NameError

使用一个还未被赋予对象的变量。

8、SyntaxError

Python 代码非法,代码不能编译(语法错误,写错了)。

9、TypeError

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

10、UnboundLocalError

试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它。

11、ValueError

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

三、处理

Python 解释器检测到错误,触发异常(也允许程序员自己触发异常)。

异常处理

程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关)。
如果捕捉成功则进入另外一个处理分支,执行为其定制的逻辑,使程序不会崩溃,这就是异常处理

用处

程序开发时,很难将所有的特殊情况都处理的面面俱到,通过异常捕获可以针对突发事件做集中的处理,从而保证程序的稳定性和健壮性。

当 Python 解释器抛出异常时,最后一行错误信息的第一个单词,就是错误类型。

1、捕获异常

格式一
try … except …

# 例一
try:
    print(a)
except:
    print('出现错误')

# 运行结果:
# 出现错误
# 例二
try:
    a
except IndexError as e:
    print(e)

# 运行结果:
# NameError: name 'a' is not defined
# 例三
try:
    a
except Exception as e:  # 万能异常:Exception 可以捕获任意异常
    print(e)
    
# 运行结果:
# name 'a' is not defined

如果想要的效果是,无论出现什么异常,统一丢弃,或者使用同一段代码逻辑去处理它们,那么只有一个 Exception 就足够了。

如果想要的效果是,对于不同的异常需要定制不同的处理逻辑,那就需要用到多分支了。

# 多分支
try:
    a
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except NameError as e:
    print(e)
    
# 运行结果:
# name 'a' is not defined

格式二

try … except … else

在 if 中,else 的作用是当条件不满足时执行的实行。

try … except … else 中也是如此,即如果没有捕获到异常,那么就执行 else 中的事情。

else 只有在没有异常时才会执行的代码。

try:
    a = 1
    print(a)
except NameError:
    print('出现错误')
else:
    print('没有捕获到异常')
    
# 运行结果:
# 1
# 没有捕获到异常

格式三

try … except … finally …

finally 无论是否有异常都会执行的代码。

在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用 finally。

比如文件关闭,释放锁,把数据库连接返还给连接池等。

try:
    print(a)
except NameError:
    print('出现错误')
finally:
    print('哈哈哈')

# 运行结果:
# 出现错误
# 哈哈哈

2、完整捕获异常

try:
    n = int(input('请输入整数:'))  # 尝试执行的代码
    print(8/n)
except ValueError:
    print('请输入正确的数据')  # 针对错误类型1,对应的代码处理
except ZeroDivisionError:  # 针对错误类型2,对应的代码处理
    print('除0错误')
except Exception as e:
    print('未知错误 %s' % e)
else:
    print('没有异常才会执行的代码')
finally:
    print('无论是否有异常,都会执行的代码')

# 运行结果:
# 请输入整数:qw
# 请输入正确的数据
# 无论是否有异常,都会执行的代码

3、异常的传递

从产生异常的地方开始传递到调用异常的地方,如果一直没有处理异常,会一直传递到主函数,然后停止,程序并报出异常信息。

1、在开发中,可以在主函数中增加异常捕获。

2、而在主函数中调用的其它函数,只要出现异常,都会传递到主函数的异常捕获中。

3、这样就不需要在代码中,增加大量的异常捕获,能够保证代码的整洁。

# 例一:
def funa():
    return int(input('请输入整数:'))
def funb():
    return funa()

try:
    print(funb())
except Exception as e:
    print('错误: %s'%e)
    
# 运行结果:
# 请输入整数:qw
# 错误: invalid literal for int() with base 10: 'qw'
# 例二:
def test():
    num = int(input('请输入:'))
    return 10 / num

def test2():
    print(test())
try:
    test2()
except ValueError:
    print('类型错误,输入不正确')
except ZeroDivisionError:
    print('非零')
else:
    print('运行成功')
finally:
    print('最后执行')

# 运行结果:
# 请输入:qw
# 类型错误,输入不正确
# 最后执行

4、抛出异常

Python 中提供了一个 Exception 异常类。

应用场景:

在开发中,除了代码执行出错 Python 解释器会抛出异常之外,

还可以根据应用程序特有的业务需求主动抛出异常

主动抛出异常分两步:

1、创建一个 Exception(‘XXX’) 的对象, XXX 为异常提示信息。

2、raise 抛出这个对象(异常对象)。

# 例一:
def funa():
    raise Exception('抛出一个异常')  # 异常被抛出,print 函数无法执行
    print('啊哈哈')

funa()

# 运行结果:
# Traceback (most recent call last):
#   File "F:\Python\pythonProject\main.py", line 6, in <module>
#     funa()
#   File "F:\Python\pythonProject\main.py", line 3, in funa
#     raise Exception('抛出一个异常') #异常被抛出,print函数无法执行
# Exception: 抛出一个异常
# 例二:
def funa():
    pwd = input('请输入密码:')
    if len(pwd) >=6:  # 判断密码长度
        return pwd

    # 创建异常对象 - 使用异常的错误信息字符串作为参数
    ex = Exception('长度不够')
    raise ex # 抛出异常对象

try:
    upwd= funa()
    print(upwd)
except Exception as e:
    print('错误:%s'%e)

使用 try … except 的方式

1、把错误处理和真正的工作分开来

2、代码更易组织,更清晰,复杂的工作任务更容易实现

3、毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了

try … except 应该尽量少用,因为它本身就是附加程序的一种异常处理的逻辑,与主要的工作是没有关系的。

这种东西加的多了,会导致代码可读性变差,只有在有些异常无法预知的情况下,才应该加上 try … except,其它的逻辑错误应该尽量修正。

记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值