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

计数调用装饰器:为何要将inner.call_count重置为0?

装饰器计数器初始化问题解析

问题背景

以下是用于统计函数调用次数的装饰器代码:

from functools import wraps

def counting_calls(func):
    @wraps(func)
    def inner(*args, **kwargs):
        inner.call_count += 1
        return func(*args, **kwargs)
    inner.call_count = 0
    return inner

测试代码:

@counting_calls
def add(a: int, b: int) -> int:
    '''return sum of 2 ints'''
    return a + b

print(add(10, b=20))
print(add(30, 5))
print(add(3, 5))
print(add(4, 5))
print('num calls =', add.call_count)
print(add(11, 5))
print('num calls =', add.call_count)

疑问:为何要设置inner.call_count = 0?这一操作是否会导致call_count始终被重置为0,无法保存总调用次数?

解答

  • 初始化inner.call_count = 0的必要性:
    这是为闭包函数inner创建并初始化一个计数器属性。如果不做这一步,第一次调用被装饰后的函数时,执行inner.call_count += 1会直接抛出AttributeError——因为此时inner还没有call_count这个属性,Python无法对一个不存在的属性做自增操作。

  • 不会出现反复重置的问题:
    inner.call_count = 0只在装饰目标函数的瞬间执行一次。当你用@counting_calls装饰add时,counting_calls函数会被调用一次,生成对应的inner函数,初始化它的call_count为0,之后add变量就指向了这个inner函数。后续每次调用add,都是直接调用这个已经初始化好的inner,只会执行inner.call_count += 1来累加次数,不会再回到counting_calls函数里重新设置call_count为0。

从测试代码的运行结果也能直观验证:

30
35
8
9
num calls = 4
16
num calls = 5

可以看到call_count是持续累加的,完全能正常统计总调用次数。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 17:18:10