30天学会Python编程:10. Python异常处理与调试

10.1 异常处理基础

10.1.1 异常处理机制

10.1.2 基本语法结构

try:
    # 可能引发异常的代码
except ExceptionType as e:
    # 异常处理代码
else:
    # 无异常时执行
finally:
    # 无论是否异常都执行

10.2 常见异常类型

10.2.1 内置异常层次

10.2.2 主要异常类型

表10-1 Python常见异常类型

异常类型

触发场景

示例

ValueError

值无效

int("abc")

TypeError

类型错误

"a" + 1

IndexError

索引越界

[1,2][3]

KeyError

键不存在

{}["key"]

FileNotFoundError

文件未找到

open("nonexist.txt")

ZeroDivisionError

除零错误

1/0

AttributeError

属性错误

"".no_method()

10.3 异常处理进阶

10.3.1 多异常处理

try:
    # 可能出错的代码
except (ValueError, TypeError) as e:
    print(f"输入错误: {e}")
except FileNotFoundError as e:
    print(f"文件未找到: {e.filename}")
except Exception as e:
    print(f"未知错误: {e}")

10.3.2 异常链与上下文

try:
    import nonexistent_module
except ImportError as e:
    raise RuntimeError("依赖缺失") from e

10.3.3 自定义异常

class MyAppError(Exception):
    """应用基础异常"""
    
class InvalidInputError(MyAppError):
    """输入无效异常"""
    def __init__(self, input_value):
        self.input_value = input_value
        super().__init__(f"无效输入: {input_value}")

# 使用示例
def process(data):
    if not data.isdigit():
        raise InvalidInputError(data)
    return int(data)

10.4 调试技术

10.4.1 print调试法

def complex_calculation(a, b):
    print(f"输入参数: a={a}, b={b}")  # 调试输出
    result = a * b
    print(f"中间结果: {result}")      # 调试输出
    result += 100
    return result

10.4.2 断言调试

def divide(a, b):
    assert b != 0, "除数不能为零"
    return a / b

# 触发断言
divide(10, 0)  # AssertionError: 除数不能为零

10.4.3 logging模块

import logging

# 配置日志
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='app.log'
)

def process_data(data):
    logging.debug(f"开始处理数据: {data}")
    try:
        result = int(data)
        logging.info(f"处理成功: {result}")
        return result
    except ValueError as e:
        logging.error(f"处理失败: {e}")
        raise

10.5 使用调试器

10.5.1 pdb基本命令

表10-2 pdb常用命令

命令

缩写

功能

break

b

设置断点

continue

c

继续执行

next

n

单步执行(不进入函数)

step

s

单步执行(进入函数)

where

w

显示调用栈

print

p

打印变量

list

l

显示当前代码

quit

q

退出调试器

10.5.2 调试示例

# 在代码中插入断点
import pdb; pdb.set_trace()

# 或者命令行启动
# python -m pdb script.py

10.6 单元测试

10.6.1 unittest示例

import unittest

def add(a, b):
    return a + b

class TestAdd(unittest.TestCase):
    def test_add_integers(self):
        self.assertEqual(add(1, 2), 3)
    
    def test_add_strings(self):
        self.assertEqual(add("a", "b"), "ab")
    
    def test_add_type_error(self):
        with self.assertRaises(TypeError):
            add("a", 1)

if __name__ == "__main__":
    unittest.main()

10.6.2 pytest示例

# test_sample.py
import pytest

def test_addition():
    assert 1 + 1 == 2

def test_division():
    with pytest.raises(ZeroDivisionError):
        1 / 0

# 运行测试
# pytest test_sample.py -v

10.7 性能分析

10.7.1 timeit模块

from timeit import timeit

# 测量代码执行时间
time = timeit('"-".join(str(n) for n in range(100))', number=10000)
print(f"执行时间: {time:.4f}秒")

10.7.2 cProfile分析

import cProfile

def slow_function():
    return sum(i*i for i in range(1000000))

cProfile.run('slow_function()')

10.8 综合应用举例

案例1:健壮的数据处理器

import logging
from typing import Union

logging.basicConfig(level=logging.INFO)

class DataProcessor:
    """带有完善错误处理的数据处理器"""
    
    def __init__(self, max_retries=3):
        self.max_retries = max_retries
    
    def process(self, data: Union[str, int, float]) -> float:
        """处理输入数据返回浮点数"""
        for attempt in range(1, self.max_retries + 1):
            try:
                value = float(data)
                if value < 0:
                    logging.warning(f"负值输入: {value}")
                return value
            except (ValueError, TypeError) as e:
                logging.error(f"尝试 {attempt} 失败: {e}")
                if attempt == self.max_retries:
                    raise InvalidInputError(data) from e
                continue
            except Exception as e:
                logging.critical(f"未知错误: {e}")
                raise

# 使用示例
processor = DataProcessor()
try:
    result = processor.process("123.45")
    print(f"处理结果: {result}")
except InvalidInputError as e:
    print(f"处理失败: {e}")

案例2:自动化测试框架

import unittest
from unittest.mock import patch

class TestUserService(unittest.TestCase):
    @patch('user_service.Database')  # 模拟数据库
    def test_user_creation(self, mock_db):
        # 设置模拟返回值
        mock_db.return_value.insert.return_value = 1001
        
        from user_service import create_user
        user_id = create_user("test@example.com", "password123")
        
        # 验证结果
        self.assertEqual(user_id, 1001)
        mock_db.return_value.insert.assert_called_once_with(
            "users", {"email": "test@example.com", "password": "password123"}
        )

    def test_invalid_email(self):
        from user_service import create_user
        with self.assertRaises(ValueError):
            create_user("invalid-email", "password")

if __name__ == "__main__":
    unittest.main()

10.9 学习路线图

10.10 学习总结

  1. 核心要点
  2. 掌握try-except-finally完整结构
  3. 理解异常类继承体系
  4. 熟练使用调试工具
  5. 能够编写单元测试
  6. 实践建议
  7. 异常处理要具体化(避免裸except)
  8. 使用logging替代print调试
  9. 重要操作添加断言检查
  10. 为关键功能编写测试用例
  11. 进阶方向
  12. 异常链与上下文管理
  13. 异步代码调试
  14. 性能优化分析
  15. 测试覆盖率分析
  16. 常见陷阱
  17. 过度捕获异常掩盖问题
  18. 忘记处理finally中的异常
  19. 测试用例不够独立
  20. 调试后遗留的调试代码

持续更新Python编程学习日志与技巧,敬请关注!


#编程# #python# #在头条记录我的2025#


相关文章

熬夜也值得学习练手的108个Python项目(附源码),太实用了!

现在学编程的人越来越多,Python 因为简单好上手、功能又强大,成了很多人的首选。不管是做数据分析、人工智能,还是写网络程序、自动化脚本,Python 都能派上用场。而且它诞生的时间比网页还早,作为...

Python 编程 10 个经典操作

一、变量赋值与交换在 Python 中,变量赋值非常简单,直接使用等号=即可。例如:这里将整数5赋值给变量a,将字符串"Hello, Python!"赋值给变量b。那如果要交换两个变量...

Python程序员删库前夜留下的100道救命代码!这份禁传题库速拿!

在程序员的江湖里,流传着无数关于 “删库跑路” 的传说,但这次,一位神秘的 Python 程序员在删库前夜,留下了一份堪称 “救命宝典” 的代码题库。这份题库涵盖了 Python 从基础到高级的核心技...

量化交易前你需要知道的python基础(二)(附代码案例)

今天我们继续来学习量化交易所需的基础python知识,今天会给大家好好讲讲python中函数、循环和数据分析相关的内容,也是平常量化交易中非常重要的内容。一、Python 函数函数是 Python 编...

Python入门到进阶,看这10本书就够了(附PDF)看完少走一半弯路

宝子们,刚踏入 Python 编程世界,是不是被五花八门的学习资料弄得眼花缭乱?别愁啦,今天我直接给大家奉上一份超豪华大礼包 ——16 本 Python 超全电子书合集(附 PDF 版)包括Pytho...

10 个极其有用的 Python 自动化脚本

在现代职场中,重复性和耗时的任务常常占据大量时间,影响工作效率。Python作为一种高效、易用的编程语言,提供了丰富的库和工具,能够帮助打工人自动化处理日常任务,提升工作效率。以下是十个必备的Pyth...