【问题标题】:Count how many times each function gets called计算每个函数被调用的次数
【发布时间】:2022-11-19 13:49:09
【问题描述】:

我想计算每个函数被调用了多少次。 我有一个包装器来进行计数并将其保存到全局变量中

def counter(f):
    global function_calls
    function_calls = 0

    def wrapper(*args, **kwargs):
        global function_calls
        function_calls += 1
        return f(*args, **kwargs)

    return wrapper

然后其他两个函数被装饰用于计数

@counter
def square(x):
    return x * x


@counter
def addition_by_self(x):
    return x + x

现在,当我每次调用该函数五次时,全局变量 function_calls 返回 10。这是有道理的。

print(square(x=4))
print(square(x=4))
print(square(x=4))
print(square(x=4))
print(square(x=4))

print(addition_by_self(x=4))
print(addition_by_self(x=4))
print(addition_by_self(x=4))
print(addition_by_self(x=4))
print(addition_by_self(x=4))

print(f"Number of the function got called: {function_calls}")

运行文件给出输出。

16
16
16
16
16
8
8
8
8
8
Number of the function got called: 10

现在我需要一些关于如何使装饰器返回每个函数被调用的次数的解决方案或想法,而不是所有调用的聚合。我可能还有其他功能需要跟踪它们也被调用的次数。

本质上我想做类似print(function_calls) # or something proper的事情 然后像这样出去:sqaure got called 5 times and addition_by_self got called 5 times

【问题讨论】:

    标签: python python-3.x decorator python-decorators


    【解决方案1】:

    不是单个全局int,而是将每个函数的计数存储在dict 中。

    def counter(f):
        global function_calls
        function_calls = {}
    
        def wrapper(*args, **kwargs):
            global function_calls
            function_calls[f.__name__] += 1
            return f(*args, **kwargs)
    
        return wrapper
    

    f 可能比 f.__name__ 更好(多个不同的函数可以具有相同的名称),但这只是一个简单的例子。

    【讨论】:

    • 出于某种原因,我得到一个键错误,为什么我执行该函数时出现来自function_calls[f.__name__] += 1 的错误。那是我调用装饰函数square(4)的时候
    【解决方案2】:

    使用列表和属性:

    def counter(f):
        global funs
        try:
            len(funs)
        except NameError:
            funs = []
        funs.append(f)
        f.function_calls = 0
    
        def wrapper(*args, **kwargs):
            f.function_calls += 1
            return f(*args, **kwargs)
    
        return wrapper
    
    @counter
    def square(x):
        return x * x
    
    
    @counter
    def addition_by_self(x):
        return x + x
    
    for i in range(10):
        print(square(3))
        print(addition_by_self(2))
        print(addition_by_self(4))
    
    for f in funs:
        print(f'function: {f.__name__}, calls: {f.function_calls}')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-10
      • 1970-01-01
      • 2021-01-09
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      • 2017-04-30
      • 2021-12-22
      相关资源
      最近更新 更多