You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何适配任意参数函数 用装饰器实现通用计时功能

原生实现任意参数函数执行耗时统计方案

你不需要手动判断参数个数写分支,Python原生的可变参数和解包语法可以直接适配任意合法参数组合的函数,完全不需要依赖第三方库。

核心原理

Python中*和**两个符号可以实现可变参数的打包与解包:

  • 定义函数时写*args会把传入的所有多余位置参数打包为元组
  • 定义函数时写**kwargs会把传入的所有多余关键字参数打包为字典
  • 调用函数时写*可迭代对象会把对象拆分为一个个独立的位置参数传入
  • 调用函数时写**字典会把字典拆分为一个个独立的关键字参数传入

靠这个特性就可以自动适配任意参数数量的函数,只要传入的参数和目标函数的定义匹配就能正常运行。


方案1:普通函数传参实现

直接把目标函数作为第一个参数传入,后面跟原函数需要的所有参数即可,不需要提前把参数整理成列表,也不需要判断参数个数:

import time

def get_function_time(func, *args, **kwargs):
    # 短耗时场景推荐替换为time.perf_counter(),计时精度更高
    start_time = time.time()
    # 解包参数执行原函数,同时保留原函数返回值
    func_result = func(*args, **kwargs)
    cost = time.time() - start_time
    # 返回耗时和原函数执行结果,避免丢失原函数的返回值
    return cost, func_result

使用示例

# 无参函数
def func1():
    time.sleep(1)
    return "func1 finish"

# 2个位置参数的函数
def func2(a, b):
    time.sleep(0.5)
    return a + b

# 带默认参数、支持关键字传参的函数
def func3(a, b, c=3, d=None):
    time.sleep(0.2)
    return f"{a}-{b}-{c}-{d}"

# 直接按原函数的参数传参即可,不需要额外包装
cost1, res1 = get_function_time(func1)
cost2, res2 = get_function_time(func2, 10, 20)
cost3, res3 = get_function_time(func3, 1, 2, d="test")

print(cost1, res1)
print(cost2, res2)
print(cost3, res3)

如果你之前习惯把参数整理到列表里传递,也只需要在调用时直接解包列表即可,不需要写分支判断长度:

def get_function_time_list_params(func, param_list: list = None, param_dict: dict = None):
    param_list = param_list or []
    param_dict = param_dict or {}
    start = time.time()
    res = func(*param_list, **param_dict)
    return time.time() - start, res

方案2:装饰器实现(更常用的无侵入方案)

如果需要批量给多个函数加耗时统计,用装饰器可以做到不修改原函数的调用逻辑,代码更简洁:

import time
from functools import wraps

def timer(func):
    # 加wraps装饰器可以保留原函数的元信息(比如函数名、注释文档)
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        cost = time.time() - start
        print(f"[Timer] 函数 {func.__name__} 执行耗时: {cost:.4f}s")
        return res
    return wrapper

使用示例

直接给需要统计耗时的函数加上@timer装饰器即可,后续调用原函数的时候会自动打印耗时:

@timer
def test_func(name, age, city="Beijing"):
    time.sleep(0.3)
    return f"User: {name}, {age} years old, live in {city}"

# 正常调用原函数,不需要修改传参逻辑
result = test_func("Zhang San", 25, city="Shanghai")
print(result)

补充说明

如果需要统计执行时间非常短的函数(比如毫秒、微秒级),建议把time.time()替换为time.perf_counter(),后者是Python专门为性能基准测试设计的计时接口,精度更高,不会受系统时间同步调整的影响。

内容的提问来源于stack exchange,提问作者offerrall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 18:54:24