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}")
相关推荐
Stecurry_302 小时前
Springboot整合SpringMVC --从0到1
java·spring boot·后端
Serene_Dream2 小时前
NIO 的底层机理
java·jvm·nio·mmap
Rolei_zl2 小时前
AIGC(生成式AI)试用 45 -- DocsGPT 与 Python开发 1
python·aigc
怣502 小时前
MySQL WHERE子句完全指南:精准过滤数据的艺术
数据库·mysql
Yeats_Liao2 小时前
微调决策树:何时使用Prompt Engineering,何时选择Fine-tuning?
前端·人工智能·深度学习·算法·决策树·机器学习·prompt
skywalker_112 小时前
多线程&JUC
java·开发语言·jvm·线程池
晚霞的不甘2 小时前
Flutter for OpenHarmony 实现 iOS 风格科学计算器:从 UI 到表达式求值的完整解析
前端·flutter·ui·ios·前端框架·交互
黎雁·泠崖2 小时前
Java基础核心能力总结:从语法到API的完整知识体系
java·开发语言
大鳥2 小时前
第一章 - 数据仓库是什么
大数据·数据库·hive