解:
from bdb import Bdbimport sysclass RecursionDetected(Exception): passclass 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): pre = frame.f_pre if pre in self.stack: raise RecursionDetected self.stack.add(pre) def user_return(self, frame, return_value): self.stack.remove(frame.f_pre)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 productassert 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次。



