7.适合新手小白学习Python的异常处理(Exception)

一、什么是异常?

异常是程序在运行时期产生的错误,会直接导致程序中断执行。它区别于编译错误(语法错误),是代码逻辑合法但运行时遇到意外情况引发的问题,比如:

  • 除零错误 ZeroDivisionError
  • 文件不存在错误 FileNotFoundError
  • 类型不匹配错误 TypeError

二、为什么要使用异常处理?

  1. 避免程序崩溃:让程序在遇到错误时优雅降级,而不是直接终止。
  2. 精准定位问题:捕获异常后可以输出详细错误信息,快速定位问题。
  3. 保证资源释放 :通过 finally 确保文件、网络连接等资源被正确释放。
  4. 提升用户体验:可以给用户友好的错误提示,而不是生硬的报错信息。

三、Python 异常处理核心语法

  1. 基础格式
python 复制代码
try:
    # 可能发生异常的代码块
    pass
except 异常类型 as e:
    # 异常发生时的处理逻辑
    pass
  • try:包裹可能出现异常的代码。
  • except:捕获指定类型的异常,并执行处理逻辑。
  • as e:将异常对象重命名为 e,方便查看错误详情。
  1. else 语法

try 代码块没有发生异常 时,会执行 else 中的代码。

python 复制代码
try:
    # 可能发生异常的代码
    pass
except 异常类型 as e:
    # 异常处理逻辑
    pass
else:
    # 无异常时执行的代码
    pass
  1. finally 语法

无论 try 代码块是否发生异常,finally 中的代码一定会执行,通常用于释放资源(如关闭文件、数据库连接)。

python 复制代码
try:
    # 可能发生异常的代码
    pass
except 异常类型 as e:
    # 异常处理逻辑
    pass
finally:
    # 无论是否异常都会执行的代码
    pass

四、实战案例

  1. 基础异常处理
python 复制代码
print("start...running...")

# 编译时无语法错误,但运行时会触发除零异常
try:
    x = 1 / 0  # 分母为0,触发 ZeroDivisionError
except ZeroDivisionError as e:
    print("这里发生了异常问题,请及时处理:", e)

运行结果

python 复制代码
start...running...
这里发生了异常问题,请及时处理: division by zero
  1. 捕获文件不存在异常
python 复制代码
try:
    # 尝试打开一个不存在的文件
    with open("test_exception.txt", "r", encoding="utf-8") as f:
        f.read()
except BaseException as e:
    print(e)  # 打印异常对象,输出:[Errno 2] No such file or directory: 'test_exception.txt'

说明

  • BaseException 是所有异常的父类,可以捕获任何类型的异常,适合调试阶段使用。
  1. elsefinally 组合使用
python 复制代码
try:
    x = int(input("用户输入一个整数:"))
    print(1 / x)
except Exception as e:
    print(e)
else:
    print("异常没有发生,不必理会")
finally:
    print("异常无论发生或不发生,都执行,一般用来释放资源")
  • 输入合法整数且不为 0 → 执行 try + else + finally
  • 输入非整数或 0 → 执行 except + finally
  1. finally 释放文件资源
python 复制代码
try:
    file = open("io_exception.txt", "w", encoding="utf-8")
    file.write("zhangsan")
except Exception as e:
    print("写入出现错误,请及时修正")
finally:
    file.close()  # 确保文件被关闭
    print(file.closed)  # 验证文件是否关闭,输出:True

print("end....running")

五、多异常处理

1.一次性捕获多个异常

当多个异常的处理逻辑相同时,可以将它们放在同一个 except 块中,用元组包裹异常类型。

python 复制代码
# #案例:输入一个整数并存储在文件
input_number,mode = (input("请输入一个整数")).split(" ")
try:
    with open("test_many_exception",mode,encoding="utf-8") as f:
        f.write(str(1/int(input_number)))
except (FileNotFoundError,ZeroDivisionError) as e:
    print("异常信息:",e)

核心逻辑

  • 将多个异常类型放在一个元组中,一次捕获。
  • 所有捕获到的异常共用同一套处理逻辑。
  • 适合处理不同异常但错误提示或处理方式一致的场景。

2 .多次捕获异常

当不同异常需要不同处理逻辑时,可以使用多个 except 块,按 "子类异常在前、父类异常在后" 的顺序捕获。

python 复制代码
try:
    with open("test.txt", "r", encoding="utf-8") as f:
        f.read()
#多次抓取的情况一般会选择从子类依次进行
except FileNotFoundError as e:
    print(f"文件不存在错误:{e}")
except OSError as e:
    print(f"系统错误:{e}")
except Exception as e:
    print(f"其他异常:{e}")
  • 异常捕获会按顺序匹配,一旦匹配成功就不再向下执行。
  • 必须将更具体的子类异常(如 FileNotFoundError)放在前面,通用的父类异常(如 Exception)放在后面。
  • 适合需要为不同异常定制处理逻辑的场景。

六、自定义异常

当内置异常无法满足业务需求时,我们可以通过继承 Exception 类来定义自己的异常,让错误信息更具业务语义。

1.定义自定义异常

python 复制代码
class AuthenticationException(Exception):
    """自定义认证异常,用于登录场景的错误提示"""
    def __init__(self, message):
        super().__init__(message)
   

2 .抛出自定义异常

在业务逻辑中,当触发特定错误时,使用 raise 关键字抛出自定义异常。

python 复制代码
# 模拟数据库中的用户名和密码
username_database = "zhangsan"
password_database = "111"

def login(username, password):
    if username != username_database:
        raise AuthenticationException("用户不存在,请先注册")
    elif password != password_database:
        raise AuthenticationException("密码错误,请重新输入")
    else:
        print("success....")
  • 使用 raise 关键字主动抛出异常。
  • 异常信息可以直接携带业务场景的具体提示,让错误更易理解。

3 .捕获并处理自定义异常

python 复制代码
import time

if __name__ == "__main__":
    username, password = input("请输入用户名和密码,使用空格隔开:").split(" ")
    try:
        login(username, password)
    except AuthenticationException as e:
        # 记录异常日志到文件
        with open("log_login.txt", "a+", encoding="utf-8") as f:
            log_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            f.write(f"出现时间:{log_time},出现的问题:{e}\n")
        print(f"登录失败:{e}")
相关推荐
Emotional。4 小时前
2025 年度技术总结与规划:AI 时代的开发者成长之路
人工智能·python·ai·langchain
huohaiyu4 小时前
从URL到页面的完整解析流程
前端·网络·chrome·url
阿星AI工作室6 小时前
一个简单Demo彻底理解前后端怎么连的丨Figma + Supabase + Vercel
前端·人工智能
Drifter_yh6 小时前
【黑马点评】Redisson 分布式锁核心原理剖析
java·数据库·redis·分布式·spring·缓存
鸽鸽程序猿6 小时前
【Redis】zset 类型介绍
数据库·redis·缓存
z玉无心6 小时前
Redis
数据库·redis·oracle
予枫的编程笔记6 小时前
【Redis核心原理篇2】Redis 单线程模型:为什么单线程还能这么快?
数据库·redis·缓存
aircrushin6 小时前
一拍即传的平替,完全免费的实时照片墙!
前端
fengxin_rou6 小时前
一文吃透 Redis 压缩列表、listpack 及哈希表扩容与并发查询
数据库·redis·散列表
一只鹿鹿鹿6 小时前
智慧水利一体化建设方案
大数据·运维·开发语言·数据库·物联网