如何在不使用Python中的全局变量的情况下跟踪递归调用的数量。例如,如何修改以下函数以跟踪调用次数?
def f(n):
if n == 1:
return 1
else:
return n * f(n-1)
print f(5)
答案 0 :(得分:10)
这是一个不使用全局的巧妙技巧:你可以在函数本身中存储计数器。
def f(n):
f.count += 1
if n == 1:
return 1
else:
return n * f(n-1)
之后:
>>> f.count = 0 # initialize the counter
>>> f(5)
120
>>> f.count
5
>>> f(30)
265252859812191058636308480000000L
>>> f.count
35
无论如何,它处理“所有通话”的情况。
答案 1 :(得分:6)
正如德尔南所说,如果你想要所有的电话永远,那么没有全球性的话就不可能,所以我假设你只是想要电话深度,你只需要需要添加返回值
def f(n):
if n == 1:
return 1,0
else:
x, call_depth= f(n-1)
return n * x, call_depth+1
如果您正在处理多个递归调用,您可以执行max(call_depth1, call_depth2)
(深度最长的调用树)或只将两者相加(实际调用的总数)
答案 2 :(得分:6)
此方法将为您提供总函数运行的次数:
def f(n):
if hasattr(f,"count"):
f.count += 1
else:
f.count = 1
if n == 1:
return 1
else:
return n * f(n-1)
答案 3 :(得分:3)
这是一种使用堆栈而不是全局变量的方法。如图所示,它统计了函数的调用次数,包括初始函数,而不仅仅是函数对自身的递归调用次数。要做到这一点,只需将ncalls += 1
移到else
语句的开头。
def f(n, ncalls=0):
ncalls += 1
if n == 1:
return 1, ncalls
else:
res, ncalls = f(n-1, ncalls)
return n * res, ncalls
for n in xrange(1, 6):
print 'f({}): {:4d} ({} calls)'.format(n, *f(n))
输出:
f(1): 1 (1 calls)
f(2): 2 (2 calls)
f(3): 6 (3 calls)
f(4): 24 (4 calls)
f(5): 120 (5 calls)
答案 4 :(得分:0)
你可以添加一个参数来保持调用的计数(需要是可变的),它在函数的开头递增。