有没有一种方法可以检查函数是否在python中是递归的?
问题内容:
我想为一个练习编写一个测试功能,以确保正确实现一个功能。
所以我想知道,有没有一种方法,给定函数“ foo”,以检查是否以递归方式实现?
如果它封装了递归函数并使用它,它也将计数。例如:
def foo(n):
def inner(n):
#more code
inner(n-1)
return inner(n)
这也应被认为是递归的。
请注意,我想使用 外部 测试功能来执行此检查。无需更改功能的原始代码。
问题答案:
解:
from bdb import Bdb
import sys
class RecursionDetected(Exception):
pass
class RecursionDetector(Bdb):
def do_clear(self, arg):
pass
def __init__(self, *args):
Bdb.__init__(self, *args)
self.stack = set()
def user_call(self, frame, argument_list):
code = frame.f_code
if code in self.stack:
raise RecursionDetected
self.stack.add(code)
def user_return(self, frame, return_value):
self.stack.remove(frame.f_code)
def test_recursion(func):
detector = RecursionDetector()
detector.set_trace()
try:
func()
except RecursionDetected:
return True
else:
return False
finally:
sys.settrace(None)
用法/测试示例:
def factorial_recursive(x):
def inner(n):
if n == 0:
return 1
return n * factorial_recursive(n - 1)
return inner(x)
def factorial_iterative(n):
product = 1
for i in xrange(1, n+1):
product *= i
return product
assert test_recursion(lambda: factorial_recursive(5))
assert not test_recursion(lambda: factorial_iterative(5))
assert not test_recursion(lambda: map(factorial_iterative, range(5)))
assert factorial_iterative(5) == factorial_recursive(5) == 120
本质上,test_recursion
它接受没有参数的可调用对象,对其进行调用,然后返回True
该可调用对象在执行过程中的任何时候是否在堆栈中两次出现相同的代码,False
否则返回。我认为这可能不是OP想要的。例如,可以很容易地对其进行修改,以测试同一代码在特定时刻是否在堆栈中出现了10次。