使用装饰器计算 python 中的函数调用
Count function calls in python using decorator
我在 class 的一篇笔记中看到了下面的 python 片段。我理解高阶函数的概念和这里使用的记忆技术。但是我对 counted_fib 和 fib 在最后几次分配后实际指的是什么感到困惑。谁能给我解释一下?
def count(f):
def counted(n):
counted.call_count += 1
return f(n)
counted.call_count = 0
return counted
def memo(f):
cache = {}
def memoized(n):
if n not in cache:
cache[n] = f(n)
return cache[n]
return memoized
def fib(n):
if n == 1 or n == 0:
return n
else:
return fib(n - 1) + fib(n - 2)
fib = count(fib)
counted_fib = fib
fib = memo(fib)
fib = count(fib)
print(fib(30))
print(fib.call_count)
print(counted_fib.call_count)
给出结果:
832040
59
31
为了计算函数被调用的次数,您可以这样做:
def fib(n):
fib.count += 1 # increase counter
if n == 1 or n == 0:
return n
else:
return fib(n - 1) + fib(n - 2)
fib.count = 0 # initialize counter
print(fib(5)) # 5
print(fib.count) # 15
你的 def count(f)
只是围绕函数 f
的装饰器,它添加了计数器所需的附加语句(计数器的初始化和增加)和 returns 装饰器功能。
def counted(n):
counted.call_count += 1
return f(n)
创建一个新函数,它有一个附加变量 counted.call_count
,每次调用该函数时该变量都会增加。 return f(n)
然后调用该函数并且 return 是 return 值。
counted.call_count = 0
return counted
然后初始化计数器并 return 修饰函数。
现在是最后 3 行:
fib = count(fib)
fib_counted = fib # save the counted function of the bare fib
fib_memo = memo(fib) # meomize fib
fib = count(fib_memo) # add a counter to the meomized version
print(fib(30))
print(fib.call_count) # 59: the meomized version was called
# ~2 times per distinct argument
print(fib_counted.call_count) # 31: i.e.: the memo called the original fib
# once per distinct argument.
使所有内容难以阅读的原因是 fib
函数调用自身(递归)。因此函数不能被称为新名称(meomized 版本除外)。这会让事情变得更容易...
我在 class 的一篇笔记中看到了下面的 python 片段。我理解高阶函数的概念和这里使用的记忆技术。但是我对 counted_fib 和 fib 在最后几次分配后实际指的是什么感到困惑。谁能给我解释一下?
def count(f):
def counted(n):
counted.call_count += 1
return f(n)
counted.call_count = 0
return counted
def memo(f):
cache = {}
def memoized(n):
if n not in cache:
cache[n] = f(n)
return cache[n]
return memoized
def fib(n):
if n == 1 or n == 0:
return n
else:
return fib(n - 1) + fib(n - 2)
fib = count(fib)
counted_fib = fib
fib = memo(fib)
fib = count(fib)
print(fib(30))
print(fib.call_count)
print(counted_fib.call_count)
给出结果:
832040
59
31
为了计算函数被调用的次数,您可以这样做:
def fib(n):
fib.count += 1 # increase counter
if n == 1 or n == 0:
return n
else:
return fib(n - 1) + fib(n - 2)
fib.count = 0 # initialize counter
print(fib(5)) # 5
print(fib.count) # 15
你的 def count(f)
只是围绕函数 f
的装饰器,它添加了计数器所需的附加语句(计数器的初始化和增加)和 returns 装饰器功能。
def counted(n):
counted.call_count += 1
return f(n)
创建一个新函数,它有一个附加变量 counted.call_count
,每次调用该函数时该变量都会增加。 return f(n)
然后调用该函数并且 return 是 return 值。
counted.call_count = 0
return counted
然后初始化计数器并 return 修饰函数。
现在是最后 3 行:
fib = count(fib)
fib_counted = fib # save the counted function of the bare fib
fib_memo = memo(fib) # meomize fib
fib = count(fib_memo) # add a counter to the meomized version
print(fib(30))
print(fib.call_count) # 59: the meomized version was called
# ~2 times per distinct argument
print(fib_counted.call_count) # 31: i.e.: the memo called the original fib
# once per distinct argument.
使所有内容难以阅读的原因是 fib
函数调用自身(递归)。因此函数不能被称为新名称(meomized 版本除外)。这会让事情变得更容易...