Can a Python method check if it is called internally?

Say I have a Python f and fhelp . fhelp intended to call itself recursively. f should not be called recursively. Is there a way f determine if it was recursively named?

+6
source share
2 answers

Use traceback 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 on the stack indicates that the code was called from f , the call was (in) directly recursive. The traceback.extract_stack method gives you easy access to this data. The if len(l[2] ... operator if len(l[2] ... in the example below simply counts the number of exact matches of the function name. To make it even more beautiful (thanks to agf for the idea), you can make it in the 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 
+11
source

You can use the flag set by the decorator:

 def norecurse(func): func.called = False def f(*args, **kwargs): if func.called: print "Recursion!" # func.called = False # if you are going to continue execution raise Exception func.called = True result = func(*args, **kwargs) func.called = False return result return f 

Then you can do

 @norecurse def f(some, arg, s): do_stuff() 

and if f is called again during its launch, called will be True , and it will raise exeption.

+1
source

Source: https://habr.com/ru/post/900113/


All Articles