| 30天学会Python编程:12. Python异常处理与调试
					当前位置:点晴教程→知识管理交流
					
					→『 技术文档交流 』
					
				 
 
 | 
| ValueError | |||
| TypeError | |||
| IndexError | |||
| KeyError | |||
| FileNotFoundError | |||
| ZeroDivisionError | |||
| AttributeError | 
实践建议:
try:
    with open("data.json", "r") as f:
        data = json.load(f)
    value = data["key"][5]
except (FileNotFoundError, json.JSONDecodeError) as e:
    print(f"文件错误: {e}")
except (KeyError, IndexError) as e:
    print(f"数据访问错误: {e}")
except Exception as e:
    print(f"未知错误: {e}")
    # 记录日志并重新抛出
    logging.exception("处理失败")
    raise
技巧:
try:
    import third_party_module
except ImportError as e:
    raise RuntimeError("缺少必要依赖") from e
应用场景举例:
class AppError(Exception):
    """应用基础异常"""
    
classInvalidInputError(AppError):
    """输入无效异常"""
    def__init__(self, input_value, message="无效输入"):
        self.input_value = input_value
        super().__init__(f"{message}: {input_value}")
# 使用示例
defvalidate_email(email):
    if"@"notin email:
        raise InvalidInputError(email, "邮箱格式错误")
    return email
设计原则:
def calculate(a, b):
    print(f"[DEBUG] 输入: a={a}, b={b}")
    result = a / b
    print(f"[DEBUG] 中间结果: {result}")
    return result * 100
适用场景:
局限性:
def withdraw(account, amount):
    assert amount > 0, "取款金额必须大于0"
    assert amount <= account.balance, "余额不足"
    account.balance -= amount
    return account.balance
实践建议:
import logging
# 配置日志系统
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    filename='app.log'
)
logger = logging.getLogger(__name__)
defprocess_data(data):
    logger.debug(f"开始处理数据: {data}")
    try:
        result = complex_operation(data)
        logger.info(f"处理成功: {result}")
        return result
    except ValueError as e:
        logger.error(f"处理失败: {e}", exc_info=True)
        raise
日志级别:
优势:
# script.py
def factorial(n):
    result = 1
    for i in range(1, n+1):  # 在此行设置断点
        result *= i
    return result
if __name__ == "__main__":
    import pdb; pdb.set_trace()  # 启动调试器
    print(factorial(5))
调试流程:
python script.pyp n, p resultn或sc替代方案:
import unittest
defdivide(a, b):
    if b == 0:
        raise ValueError("除数不能为零")
    return a / b
classTestMathOperations(unittest.TestCase):
    deftest_divide_normal(self):
        self.assertEqual(divide(10, 2), 5)
    
    deftest_divide_zero(self):
        withself.assertRaises(ValueError) as context:
            divide(10, 0)
        self.assertEqual(str(context.exception), "除数不能为零")
    
    @unittest.skip("待实现")
    deftest_negative_division(self):
        pass
if __name__ == "__main__":
    unittest.main()
# test_math.py
import pytest
deftest_addition():
    assert1 + 1 == 2
deftest_division_by_zero():
    with pytest.raises(ValueError, match="除数不能为零"):
        divide(10, 0)
@pytest.mark.parametrize("a,b,expected", [
    (10, 2, 5),
    (20, 4, 5),
    (15, 3, 5)
])
deftest_divide_cases(a, b, expected):
    assert divide(a, b) == expected
测试实践:
from timeit import timeit
# 测量列表推导式性能
list_comp_time = timeit('[x**2 for x in range(1000)]', number=10000)
# 测量生成器表达式性能
gen_exp_time = timeit('(x**2 for x in range(1000))', number=10000)
print(f"列表推导: {list_comp_time:.4f}秒")
print(f"生成器表达式: {gen_exp_time:.4f}秒")
import cProfile
def process_data():
    # 模拟数据处理
    data = [i**2 for i in range(10000)]
    return sum(data) / len(data)
# 运行性能分析
cProfile.run('process_data()', sort='cumulative')
分析要点:
优化策略:
import logging
from typing importUnion
classDataProcessor:
    """带有完善错误处理的数据处理器"""
    
    def__init__(self, max_retries=3):
        self.max_retries = max_retries
    
    defprocess(self, data: Union[str, int, float]) -> float:
        """处理输入数据返回浮点数"""
        for attempt inrange(1, self.max_retries + 1):
            try:
                value = float(data)
                logging.info(f"成功转换: {data} -> {value}")
                return value
            except (ValueError, TypeError) as e:
                logging.warning(f"尝试 {attempt} 失败: {e}")
                if attempt == self.max_retries:
                    raise InvalidInputError(data) from e
            except Exception as e:
                logging.error(f"未知错误: {e}")
                raise
设计解释:

优秀的程序员不是不犯错误,而是知道如何高效地处理错误并从中学习。
掌握异常处理和调试技能,能使我们从普通开发者蜕变为专业的Python开发者。持续练习,编写更健壮、更可靠的Python应用程序!
阅读原文:原文链接