Python方法可以检查它是否已从内部调用?

Jos*_*ian 10 python recursion introspection inspect

假设我有一个Python函数ffhelp.fhelp旨在递归地调用自己.f不应该递归调用.有没有办法f确定它是否已被递归调用?

jro*_*jro 15

使用traceback模块:

>>> 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
Run Code Online (Sandbox Code Playgroud)

因此,如果堆栈中的任何条目指示代码是从中f调用的,则调用是直接递归的.该traceback.extract_stack方法使您可以轻松访问此数据.if len(l[2] ...以下示例中的语句只计算函数名称的完全匹配数.为了使它更漂亮(感谢agf的想法),你可以把它变成装饰者:

>>> 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
Run Code Online (Sandbox Code Playgroud)