更新时间:2023-11-10 19:12:28
使用 traceback 模块:
>>>导入回溯>>>def f(深度=0):...打印深度,traceback.print_stack()...如果深度因此,如果堆栈中的任何条目表明代码是从 f
调用的,则该调用是(in)直接递归的.traceback.extract_stack
方法使您可以轻松访问这些数据.下面示例中的 if len(l[2] ...
语句只是计算函数名称的精确匹配数.为了使它更漂亮(感谢 agf 的想法),你可以把它变成一个装饰器:
Let's say I have a Python function f
and fhelp
. fhelp
is designed to call itself recursively. f
should not be called recursively. Is there a way for f
to determine if it has been called recursively?
Use the traceback module for this:
>>> import traceback
>>> def f(depth=0):
... print depth, traceback.print_stack()
... if depth < 2:
... f(depth + 1)
...
>>> f()
0 File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
None
1 File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in f
File "<stdin>", line 2, in f
None
2 File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in f
File "<stdin>", line 4, in f
File "<stdin>", line 2, in f
None
So, if any entry in the stack indicates that the code was called from f
, the call was (in)directly recursive. The traceback.extract_stack
method gives you an easy access to this data. The if len(l[2] ...
statement in the example below simply counts the number of exact matches of the name of the function. To make it even prettier (thanks to agf for the idea), you could make it into a decorator:
>>> def norecurse(f):
... def func(*args, **kwargs):
... if len([l[2] for l in traceback.extract_stack() if l[2] == f.func_name]) > 0:
... raise Exception, 'Recursed'
... return f(*args, **kwargs)
... return func
...
>>> @norecurse
... def foo(depth=0):
... print depth
... foo(depth + 1)
...
>>> foo()
0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in func
File "<stdin>", line 4, in foo
File "<stdin>", line 5, in func
Exception: Recursed