Python高级技巧(四):异常处理机制

前言

在程序开发过程中,异常处理是每一个开发者都必须掌握的重要技能。良好的异常处理机制不仅能提升程序的健壮性,还能帮助开发者更快地定位和修复问题。Python 作为一门广泛应用的高级编程语言,提供了强大而灵活的异常处理机制,同时也支持灵活的日志记录功能,便于程序的调试与维护。

本文将系统介绍 Python 中异常的概念、常见异常类型、异常处理的基本语法与使用方式、自定义异常的创建方法,以及如何使用 logging 模块进行基本的日志记录。文章内容配有丰富的代码示例和输出结果,帮助读者更好地理解并实践这些关键技术点。无论你是刚入门 Python 还是希望巩固异常与日志相关知识的开发者,相信本文都能为你提供清晰的指导和实用的参考。

1.异常的概念

异常是一个事件,会在程序执行过程中产生,并且会影响程序的正常执行。
• 一般情况下,Python遇见错误的代码或者无法正常处理程序就会产生一个异
常并抛出。
• 异常被抛出后,可以被捕捉,捕捉后程序会按照某种机制继续运行,如果对抛
出的异常不做任何处理的话,那么程序就会终止运行。

2.常见的异常

名称描述
KeyboardInterrupt用户主动结束程序触发
AttributeError尝试访问对象没有的属性时候触发
TypeError操作非法类型的数据时触发
IndexError序列中没有索引时候触发
KeyError映射(如字典)中没有键时触发
Exception通用的异常类,用于捕捉其他所有的异常类型

2.1常见异常的代码示例

2.1.1 KeyboardInterrupt的示例

import time
for i in range(5):
    print(i)
    time.sleep(1)

输出结果为:
(这里是隔一秒输出一个,当在这五个数输出完成前就点击结束运行的话会输出KeyboardInterrupt)

#当主动结束会输出以下内容
Traceback (most recent call last):
	File"XXXX\XXX\XXX",line5,in <module>
 		time.sleep(1)
KeyboardInterrupt
#如果没有点提前结束输出以下内容
0
1
2
3
4

2.1.2 AttributeError的示例

my_str = 'abcdef'
my_str.abc()
#这里没有这个abc给它调用所以会报错

输出结果

AttributeError: 'str' object has no attribute 'abc'

2.1.3

#列表里没有下标为10的会报错
my_list = [1, 2, 3]
print(my_list[10])

输出结果为:

IndexError: list index out of range

3.异常处理机制

3.1 异常处理机制的概念

在Python中,使用try、except、finally、else等关键字来组合成不同的异常处理
方式,其中try和except是异常处理机制中的核心。
异常处理分为三种,分别为捕获单个异常、捕获多个异常和捕获全部异常,在捕
获到对应的异常后,不会再导致程序终止执行,而是会执行处理异常的代码。

3.2异常处理机制的格式语法

3.2.1 捕获单个异常

第一种:捕获单个异常

捕获单个异常
格式:
try:
	# 有可能发生异常的代码
except 某个异常:
	# 异常发生后要执行的代码
else:
	# 如果没有异常发生,在try执行完毕后执行这里的代码
finally:
	# 不管有没有捕获到异常,最后都会执行这里的代码

代码示例

try:
    x = 10
    y = 0
    print(x / y)
except ZeroDivisionError:
    print('除数不能为0')

输出结果为:

除数不能为0

3.2.2 捕获多个异常

第二种:捕获多个异常

捕获多个异常
格式:
try:
	# 有可能发生异常的代码
except (第一个异常,第二个异常):
	# 异常发生后要执行的代码
else:
	# 如果没有异常发生,在try执行完毕后执行这里的代码
finally:
	# 不管有没有捕获到异常,最后都会执行这里的代码

代码示例

try:
    print(a)
    x = 10
    y = 1
    z = x / y
except (ZeroDivisionError, NameError):
    print('除数不能为0')
else:
    print(z)

输出结果为:

try:
    print(a)
    x = 10
    y = 1
    z = x / y
except ZeroDivisionError:
    print('除数不能为0')
except NameError:
    print("命名错误")
else:
    print(z)

这里输出结果有三种情况

#第一种正常输出(前提是没有print(a))
10
#第二种 (有print(a))
命名错误
#第三种 (没有print(a)但是y = 0)
除数不能为0

第三种:捕获所有异常

捕获所有异常
格式:
try:
	# 有可能发生异常的代码
except Exception:
	# 异常发生后要执行的代码
else:
	# 如果没有异常发生,在try执行完毕后执行这里的代码
finally:
	# 不管有没有捕获到异常,最后都会执行这里的代码

代码示例

try:
    print(a)
    x = 10
    y = 0
    z = x / y
except Exception as e:
    print(e)

输出结果为:

name 'a' is not defined

3.2 异常的传递性

异常的传递性:当一个函数或方法抛出一个异常时,这个异常会被传递到调用者那里,
如果调用者没有捕获异常的话,那么程序会终止。

4.自定义异常

4.1自定义异常的概念

在Python中,使用raise关键字来手动抛出异常,其格式为:
raise Exception (arg)
• Exception用于指定要抛出的异常类型,该类型来自于Python解释器自带的异
常类型。
• arg是一个可选的参数,更多的用于提供关于异常的信息。

代码示例

import time
for i in range(100):
    print(i)
    time.sleep(1)
    raise NameError('手动抛出的某某某异常')

输出结果为:

0
NameError: 手动抛出的某某某异常

5.日志的简单应用

5.1 日志级别

在Python里,记录日志使用logging库,日志的级别从高到底分别为:
1.CRITICAL:系统崩溃级别的错误,必须立即处理
2.ERROR:运行时的错误,可能导致程序无法正常执行
3.WARNING:警告信息
4.INFO:信息性消息,程序正常运行
5.DEBUG:详细信息,通常在诊断问题时有用

5.2 运用日志级别(代码示例)

import logging
logging.basicConfig(level=logging.DEBUG)
logging.critical('这是一个critical信息')
logging.error('这是一个error信息')
logging.warning('这是一个警告信息')
logging.info('这是一个info信息')
logging.debug('这是一个debug信息')

输出结果为:

#(这些都是红色的)
CRITICAL:root:这是一个critical信息
ERROR:root:这是一个error信息
WARNING:root:这是一个警告信息
INFO:root:这是一个info信息
DEBUG:root:这是一个debug信息

5.3 打印日志信息

向指定日志文件去打印日志信息
首先你先创建一个文件命名为app.log

import logging
logging.basicConfig(filename='./app.log', level=logging.DEBUG, filemode='a', format='%(name)s - %(levelname)s - %(asctime)s- %(message)s')
logging.warning('这是一个警告信息')

输出结果为:

# app.log文件里会出现
root - WARNING - 2025-09-03 19:33:13,608- 这是一个警告信息

如图所示:
请添加图片描述

这里出现了之前我们没有学的

filemode = 'a'  #这里的a是在日志文件里去添加的意思,后面在文件操作里会讲
%(name)s:日志记录器的名字
%(levelname)s:日志级别
%(asctime)s: 时间
%(message)s: 消息本身

5.4 创建自己的日志处理器

代码示例:

import logging
logger = logging.getLogger('mylogger')
logging.basicConfig(filename='./app.log', level=logging.DEBUG, filemode='a', format='%(name)s - %(levelname)s - %(asctime)s- %(message)s')
logger.warning('这是我自己定义的日志处理器所记录的日志')

输出结果为:


mylogger - WARNING - 2025-09-03 19:36:51,110- 这是我自己定义的日志处理器所记录的日志

如图所示:(上面那一句是我们上一步生成的)请添加图片描述

总结

本文系统讲解了 Python 中异常处理与日志记录的基本概念和实际应用。通过具体的代码示例,我们了解了常见的异常类型(如 KeyboardInterrupt、AttributeError、IndexError 等)及其触发场景,掌握了如何使用 try-except-else-finally 结构捕获和处理异常,包括单个异常、多个异常和全部异常的捕获方式。

此外,我们还介绍了如何通过 raise 语句手动抛出异常,实现自定义异常类,以更好地适应项目中的特定错误处理需求。在日志部分,我们学习了如何使用 logging 模块记录不同级别的日志信息,并将其输出到控制台或指定的日志文件中,从而提升程序的可维护性和调试效率。

异常和日志是程序开发中不可或缺的组成部分。合理使用异常处理机制和日志系统,不仅能提高代码的鲁棒性,还能显著提升开发效率和系统可观测性。希望本文能帮助你在实际开发中更加得心应手地处理错误与记录运行信息。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mrliu__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值