Python中如何获取传入计时函数的目标函数名称?
解决Python函数计时的正确实现方法
原代码的核心问题
- 传参错误:调用
taketime(hello())时,hello()会立刻执行,返回的None被传给executable,此时去取executable.__name__必然报错——因为None没有该属性。而且函数已经在计时开始前执行了,计时完全无效。 - 未执行目标函数:原
taketime里只是把executable赋值给out,没有运行目标函数,导致计时结果是0(或极短的赋值时间),完全不符合需求。
正确实现方式
方法一:通用计时函数(支持带参数的函数)
修改传参逻辑,传入函数对象而非函数执行结果,同时在计时区间内执行目标函数:
import time def taketime(executable, exname=None, *args, **kwargs): # 自动获取函数名称,优先使用传入的exname if exname is None: exname = executable.__name__ # 开始计时 tic = time.time() # 执行目标函数,支持传入任意参数 out = executable(*args, **kwargs) # 结束计时 toc = time.time() # 格式化输出计时结果 print(f'Time taken for {exname}: {toc - tic:.6f} sec') return out # 测试无参函数 def hello(): print('Hello!') return # 调用时传入函数对象hello,而非hello() dd = taketime(hello) # 测试带参函数 def add(a, b): return a + b # 直接传入参数,也可以自定义函数名称 result = taketime(add, exname='整数加法', a=2, b=3) print(result) # 输出5
方法二:装饰器实现(更简洁的Python惯用写法)
用装饰器给目标函数添加计时功能,无需每次手动调用计时函数:
import time def taketime_decorator(exname=None): def decorator(func): def wrapper(*args, **kwargs): # 确定函数名称 func_name = exname or func.__name__ tic = time.time() # 执行原函数 result = func(*args, **kwargs) toc = time.time() print(f'Time taken for {func_name}: {toc - tic:.6f} sec') return result return wrapper return decorator # 给无参函数添加计时 @taketime_decorator() def hello(): print('Hello!') return # 直接调用函数即可自动计时 hello() # 给带参函数添加计时,同时自定义名称 @taketime_decorator(exname='字符串拼接') def concat_str(s1, s2): return s1 + s2 print(concat_str('Hello, ', 'World!'))
注意事项
原代码中手动传入名称(如taketime(hello(),'hello'))看似正常,但本质逻辑错误:hello()在调用taketime前就已经执行,计时的是参数传递的时间,而非函数实际执行时间,完全起不到计时作用。必须传入函数对象,在计时区间内执行函数,才能得到正确的结果。
内容的提问来源于stack exchange,提问作者msi_gerva
相关产品推荐
相关产品推荐

