如何实现Python装饰器对各函数的独立调用次数统计?
按函数独立统计调用次数的装饰器实现
你可以将全局变量替换为字典来存储每个函数的调用次数,键用函数名称或函数对象(避免重名冲突),值为对应调用次数。以下是具体实现:
基础实现(按函数名统计)
# 存储各函数调用次数的字典 function_calls = {} def counter(func): def wrapper(*args, **kwargs): # 获取函数名称作为字典键 func_name = func.__name__ # 初始化计数(如果函数未被统计过) if func_name not in function_calls: function_calls[func_name] = 0 # 调用次数+1 function_calls[func_name] += 1 # 执行原函数逻辑 return func(*args, **kwargs) return wrapper # 装饰需要统计的函数 @counter def square(x): return x ** 2 @counter def addition_by_self(x): return x + x # 测试调用各5次 for _ in range(5): square(2) addition_by_self(3) # 生成并输出统计结果 stat_str = ",".join([f"{name}被调用{count}次" for name, count in function_calls.items()]) print(stat_str)
运行后会输出:square被调用5次,addition_by_self被调用5次
优化实现(避免函数重名冲突)
如果后续可能出现不同模块下的同名函数,可以直接用函数对象作为字典的键,确保统计唯一性:
function_calls = {} def counter(func): def wrapper(*args, **kwargs): # 用函数对象本身作为键,彻底避免重名问题 if func not in function_calls: function_calls[func] = 0 function_calls[func] += 1 return func(*args, **kwargs) return wrapper # 装饰函数、测试调用部分和基础实现一致 # 输出时通过函数对象的__name__属性获取名称 stat_str = ",".join([f"{func.__name__}被调用{count}次" for func, count in function_calls.items()]) print(stat_str)
核心逻辑说明
- 用字典替代单一全局变量,实现多函数的独立计数存储
- 装饰器的
wrapper函数在每次调用被装饰函数时,先更新对应计数,再执行原函数 - 后续新增需要统计的函数,只需添加
@counter装饰器即可自动加入统计,无需修改装饰器本身
内容的提问来源于stack exchange,提问作者se7en
相关产品推荐
相关产品推荐

