【问题标题】:Python - Count number of times function passes through decoratorPython - 计算函数通过装饰器的次数
【发布时间】:2015-08-03 15:24:03
【问题描述】:

我有一个装饰器,我想在函数通过装饰器路由时增加一个计数器。到目前为止,这是我的代码

from functools import wraps
def count_check(function):
    """Returns number of times any function with this decorator is called
    """
    count = []
    @wraps(function)
    def increase_count(*args, **kwargs):
        count.append(1)
        return function(*args, **kwargs), len(count)

    return increase_count

它工作正常,直到另一个函数通过装饰器并将该函数的计数重置为 0。如何汇总总次数?

【问题讨论】:

  • 为我工作。请显示实际产生不良行为的代码。
  • 您好,没有错误,只是意外行为。例如,如果我用@count_check 装饰两个函数,它们都有自己的计数,而不是合计所有计数。
  • 如果您想要对使用@count_check 修饰的函数的所有调用进行总计,则需要一个全局计数变量

标签: python decorator python-decorators functools


【解决方案1】:

应该这样做:

from functools import wraps
def count_check(function, count=[0]):
    """Returns number of times any function with this decorator is called
    """
    @wraps(function)
    def increase_count(*args, **kwargs):
        count[0] += 1
        return function(*args, **kwargs), count[0]

    return increase_count

您也可以花哨并使用字典来单独或单独计算函数:

from functools import wraps
def count_check(function, count={}):
    """Returns number of times any function with this decorator is called
    """
    count[function] = 0
    @wraps(function)
    def increase_count(*args, **kwargs):
        count[function] += 1
        return function(*args, **kwargs), count[function], sum(count.values())

    return increase_count

演示:

@count_check
def foo():
    return 42

print(foo(), foo(), foo())

@count_check
def bar():
    return 23

print(bar(), bar(), bar())
print(foo(), foo(), foo())

打印:

(42, 1, 1) (42, 2, 2) (42, 3, 3)
(23, 1, 4) (23, 2, 5) (23, 3, 6)
(42, 4, 7) (42, 5, 8) (42, 6, 9)

【讨论】:

  • 谢谢 Stefan,正是我所需要的。
  • 刚刚学到了一些新东西。没有意识到python只评估了一次默认参数,因此每次都返回相同的可变对象。我喜欢它。
  • 我自己也很惊讶。不知道
【解决方案2】:

我会尝试类似:

from functools import wraps
count = 0
def count_check(function):
    @wraps(function)
    def increase_count(*args, **kwargs):
        global count
        count += 1
        return function(*args, **kwargs), count

    return increase_count

【讨论】:

  • 感谢 junnytony,这成功了。但是,您不认为引用全局计数是个坏主意吗?
  • 通常我尽量避免使用全局变量,但如果所有 count_check 正在计算所有用它包装的函数被调用的次数,那么这很好,因为你没有跟踪单独的函数来电。
猜你喜欢
  • 2019-12-20
  • 2017-12-11
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 2019-11-07
相关资源
最近更新 更多