Python方法可以检查它是否已经从内部调用吗? [英] Can a Python method check if it has been called from within itself?
问题描述
假设我有一个Python函数f
和fhelp
. fhelp
旨在递归调用自己. f
不应递归调用. f
是否可以确定是否已递归调用它?
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?
推荐答案
使用回溯此模块:
>>> 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
因此,如果堆栈中的任何条目指示已从f
调用了代码,则该调用是直接(递归)的. traceback.extract_stack
方法使您可以轻松访问此数据.下面示例中的if len(l[2] ...
语句仅计算函数名称的完全匹配数.要使其更漂亮(感谢agf的创意),您可以将其设置为装饰器:
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
这篇关于Python方法可以检查它是否已经从内部调用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!