高阶函数实现计时器的核心是将计时逻辑抽象为可复用的包装行为,不修改原函数,仅通过封装其调用过程来测量执行时间并返回原结果。

用高阶函数实现函数执行计时器,核心在于把“计时逻辑”抽象成可复用的包装行为,让目标函数不感知、不修改,只专注自身职责。
用函数作为参数:封装通用计时逻辑
最直接的方式是写一个接收函数并返回计时后结果的高阶函数。它不改变原函数,只在调用前后插入时间测量:
- 使用 time.perf_counter() 而非 time.time(),因前者精度更高、不受系统时钟调整影响,适合性能测量
- 计时逻辑应包裹 func(*args, **kwargs) 全过程,确保包含所有执行开销
- 返回原函数结果,保证调用方行为不变,避免副作用
示例:
import time
def time_it(func):
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
end = time.perf_counter()
print(f"{func.__name__} 耗时: {end - start:.4f} 秒")
return result
return wrapper
<h1>使用</h1><p>@time_it
def add(a, b):
time.sleep(0.1)
return a + b</p><p>add(2, 3) # 输出: add 耗时: 0.1003 秒用函数作为返回值:支持配置化计时
若需灵活控制单位、阈值或是否启用,可让高阶函数返回定制化的计时器函数:
- 外层函数接收配置参数(如单位、最小记录阈值),返回一个闭包式的计时装饰器
- 内层函数才是真正的 wrapper,捕获外层传入的配置,实现差异化行为
- 例如:只对耗时超过 0.05 秒的调用打印日志,或自动转为毫秒显示
示例(带阈值):
def time_if_slow(threshold=0.05):
def decorator(func):
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
if elapsed >= threshold:
unit = "ms" if threshold < 1 else "s"
value = elapsed * 1000 if threshold < 1 else elapsed
print(f"⚠️ {func.__name__} 较慢: {value:.2f} {unit}")
return result
return wrapper
return decorator
<p>@time_if_slow(threshold=0.02)
def fetch_data():
time.sleep(0.03)结合 functools.wraps 保留函数元信息
实际工程中,不加 @wraps(func) 会导致被装饰函数丢失 __name__、__doc__ 等属性,影响调试和文档生成:
- 在 wrapper 函数上方添加 @wraps(func),它会自动复制原函数的元数据
- 尤其在配合 help()、IDE 提示、单元测试反射时,这步不可省略
- 这是高阶函数“专业感”的关键细节,不是可有可无的装饰
扩展为可复用工具:注册与批量应用
当项目中多个函数需要统一计时策略时,可进一步升级为注册式管理:
- 维护一个函数名到计时配置的映射表
- 提供 register_timer(func, config) 接口,动态绑定计时行为
- 甚至支持运行时开关(enabled=True/False),便于测试环境关闭日志干扰
这种模式已接近轻量级监控框架雏形,本质仍是高阶函数思想的自然延伸。


















