前言
每当做搜索任务或者时间复杂度任务相关时候,就会有统计函数被调用次数的需求。通常我们的做法是在函数前面定义一个变量,每循环调用一次,变量就加一,这不失为一种办法,那么有没有更高效的方法呢?
正文
第一种方法:
当然有,那就是python的独家专属操作—> 装饰器。
废话不多说,直接上例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class CallingCounter(object): def __init__ (self, func): self.func = func self.count = 0
def __call__ (self, *args, **kwargs): self.count += 1 return self.func(*args, **kwargs)
@CallingCounter def test(): print('我被调用了')
test() print(f'我被调用了{test.count}次')
|
如果是统计class中的函数被调用的次数,就把 装饰器 装在被调用函数的前面即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class CallingCounter(object): def __init__ (self, func): self.func = func self.count = 0
def __call__ (self, *args, **kwargs): self.count += 1 return self.func(*args, **kwargs)
class Test: @CallingCounter def test(): print('我被调用了')
for i in range(10): Test.test()
print(f'我被调用了{Test.test.count}次')
|
如果你的class中有很多的self用来调用函数,那么可能会报错,提示self无xxx属性or函数。这时候就要看第二种方法
第二种方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| def call_counter(func): def helper(*args, **kwargs): helper.calls += 1 return func(*args, **kwargs) helper.calls = 0 helper.__name__= func.__name__ return helper
@call_counter def f(): pass print(f.calls)
for _ in range(10): f() print(f.calls)
def f(): pass f = call_counter(f) print(f.calls)
for _ in range(10): f() print(f.calls)
|
上面两种方法笔者都亲自做了测试,下面再介绍3个超简单的(狗头保命)
第3.1种方法(超简单)
1 2 3 4 5 6 7 8
| calls = 0
def f(): global calls calls += 1
|
第3.2种方法(超简单)
1 2 3 4 5 6
| class Test(object): def __init__(self): self.calls = 0 def f(self): self.calls += 1
|
第3.3种方法(超简单)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Test(object): calls = 0 def __init__(self): pass def f(self): Test.calls += 1
A = Test() for i in range(10): A.f() print(A.calls) print(Test().calls) print(Test.calls)
|
小结
还瞅啥,好用了就赶紧去用吧。好用回来点个赞。
本文将原创进行了整理,尊重原创,附链接1, 链接2