Python异常处理与日志记录实战指南

Hazel
Hazel
发布时间:2026-10-13| 6人浏览过
原创

本文深入解析Python中的异常处理机制,通过具体代码示例展示如何利用try-except捕获并处理日志解析中的数组越界等异常,确保程序在遇到错误数据时不中断。同时介绍Python标准库logging模块的配置方法,包括设置日志等级、输出控制台及本地文件存储,帮助开发者建立完善的错误追踪与调试体系。

Python异常处理与日志处理概述

本文总结近期在Python编程中关于异常处理与日志处理的实践经验。异常处理是软件开发中至关重要的环节。由于作者早期主要使用C++,该语言并未强制要求使用try...catch结构,因此在初期编码时往往忽略此部分。直到接触Java后,发现许多场景必须显式添加try...catch模块,但当时仅依赖Eclipse的自动补全功能或直接在类声明中使用throws Exception来规避编译错误,并未深入理解其原理。

近期在编写Python代码时,注意到Python同样广泛使用try...catch结构。为了彻底解决这一认知盲区,作者进行了深入的思考与梳理。

Python异常处理机制

Python异常处理

Python的异常处理语法结构相对简洁,基本形式如下:


try:
 ...(可能出现异常的代码)
except ...(Python内置异常类或者自己实现的异常类) as e: (或者直接except:) 
 ...(处理该异常的代码)

以往作者通常忽略异常处理,依赖控制台打印的报错行号来定位问题,随后手动排查逻辑错误。经过反思,这种做法存在两个主要缺陷:

任何未捕获的错误都会导致程序直接中断,且错误提示信息往往不够直观,导致排查错误的时间显著增加。

详细解释如下:

问题一:作者之所以长期忽略此问题,是因为过往编写的程序规模较小,即使发生异常导致中断,影响也有限。然而,若未来参与多人协作的大型模块开发,一旦某个模块抛出未捕获异常导致整个程序崩溃,后果将不堪设想。

问题二:为说明此问题,举例如下。假设需要处理一个日志文件,其内容大致如下:


Jul 16 03:27:01 node69 sced[22053]: Connection from 
Jul 16 03:27:01 node69 sced[22053]: SSH: Server;Ltype 
Jul 16 03:27:01 node69 sced[22053]: SSH: Server;Ltype
Jul 16 03:27:11 node69 sced[23417]: Connection from 
Jul 16 03:27:11 node69 sced[23417]: Connection from 
Jul 16 03:27:11 node69 sced[23417]: SSH: Server;Ltype
Jul 16 03:27:11 node69 sced[23417]: SSH: Server;Ltype
Jul 16 03:27:20 node69 sced[23454]: Connection from 
Jul 16 03:27:20 node69 sced[23454]: Connection from 

目标是提取每行字符串中的'sced'名称。直观上,使用Python一行代码即可实现:


s = line.split()[4].split('[')[0].strip(':')

该写法在数据规范时无误,但实际日志文件通常规模巨大(如百万行),且可能包含空行或截断的不完整行,例如:


Jul 16 03:27:01 node69 sced[22053]: SSH: Server;Ltype
(空行)
Jul 16 03:27:11 node69 sced[23417]: Connection from 
Jul 16 03:27:11 node69 sced[23417]: Connection from 
Jul 16 03:27:11 (只有一半的行)
Jul 16 03:27:11 node69 sced[23417]: SSH: Server;Ltype

在处理此类数据时,程序会抛出数组越界异常并立即中断。每次遇到此类问题,作者需手动分析报错行,若不清楚异常行的具体形态,排查耗时极长。更糟糕的是,解决一个问题后,若后续数据出现其他异常,仍需重复上述过程。若能一次性从头到尾处理数据,在遇到异常时打印该行信息且程序不中断,将极大提升效率。这正是异常处理语句的应用场景,代码如下:


with open(fileName, 'r',encoding = 'utf-8' ,errors='ignore') as f:
 for line in f.readlines():
 try:
  s = line.split()[4]
  s = s.split('[')[0].strip(':')
  theDict[s] = 1 if theDict.get(s,-1) == -1 else theDict[s]+1 #先得到日志的程序名出现次数的字典
 except:
  logging.exception('文件--' + fileName+'--在解析句子--'+line+'--时出现异常') #exception代表打印时也会打印出系统错误提示语句
#  raise

起初,由于不确定可能遇到的异常类型,代码中仅打印异常信息而不抛出(raise)。若希望遇到异常时停止处理后续数据,可取消raise的注释。作者认为,raise的作用类似于程序中的return语句。

作者的目标是运行一次代码,打印出所有无法处理的行。上述写法实现了这一功能,充分展示了异常处理语句的实用价值。

总结:

编程的本质是实现特定逻辑,但开发者无法穷尽所有边界情况。此时引入异常处理模块,将异常信息打印出来,有助于在出现异常时提取关键数据,进而优化程序逻辑。

Python日志处理最佳实践

日志处理

关于日志处理,作者最大的体会是以往编程时从未使用日志功能,仅依赖cout、System.out.println或print等控制台输出语句进行调试。近期因研究方向涉及日志处理,不得不深入探究其必要性。

以上述代码为例,在except块中使用logging.exception打印信息。在运行时,这与直接在控制台打印异常处理语句看似无异,但在后期运维中,日志具备两项关键附加功能:

可根据设定的日志等级筛选并打印相应的日志输出语句。

可将日志写入本地文件,便于后期回溯和查找错误。


import logging
logging.basicConfig(level=logging.DEBUG) #这句话没次第一次运行时生效,修改必须重启Console

通过日志等级控制,既能决定不同级别日志是否显示,又能指定日志存储位置。这使得开发者在无法现场调试时,仅凭日志记录即可掌握程序异常状况,极大提升了远程维护的便利性。

以上关于Python异常处理和日志处理方式的分享,旨在为读者提供参考,欢迎支持。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。