Python面试题更新 2026-08-05

请用 Python 实现一个装饰器,用于记录被装饰函数的执行时间,并说明其实现原理与适用场景。

编码实现技术原理Python

考察说明

考察 Python 装饰器语法与 functools.wraps 的使用,以及时间测量与资源清理的实践能力。

回答思路

  1. 【回答框架 1】定义一个接受函数作为参数的装饰器工厂,内部用 functools.wraps 保留原函数元信息,在 wrapper 内记录开始时间 time.perf_counter(),执行原函数后计算耗时并打印或返回。
  2. 【回答框架 2】支持可选参数,如设置日志函数或单位,通过装饰器工厂再加一层参数处理实现。
  3. 【回答框架 3】若被装饰函数是异步的,需用 async def wrapper 配合 await,并注意时间测量要包住 await 调用。
  4. 【回答框架 4】使用 contextlib.ContextDecorator 或定义一个类装饰器,可实现同时作为上下文管理器与装饰器使用,便于在 with 语句中测量。
  5. 【回答框架 5】应确保计时即使函数抛异常也能正确记录,可使用 try-finally 保证结束时间被捕获。
  6. 【关键点 1】使用 functools.wraps 保留函数名、文档字符串等元信息。
  7. 【关键点 2】推荐使用 time.perf_counter 获取高精度时间,避免 time.time 受系统时间调整影响。
  8. 【关键点 3】待处理异常时用 try-finally 保证计时逻辑完整执行。
  9. 【关键点 4】对异步函数需使用异步包装器并 await 原函数。
  10. 【关键点 5】装饰器可设计为支持参数,如自定义日志函数。
  11. 【易错点 1】若不用 functools.wraps,会导致被装饰函数的元数据丢失,影响调试与内省。
  12. 【易错点 2】对于生成器函数,普通包装器只测量迭代开始时间而忽略生成过程,需用 yield from 或专门处理。
  13. 【易错点 3】在高并发场景下使用全局计时器可能引入竞争,但通常测量单次执行不影响。