getrecursiondepth

Andrew Dalke adalke at mindspring.com
Thu Sep 30 14:28:30 EDT 2004


Me:
>>Try this as a alternate solution for your style
>>of use.  It's still not the right one because it
>>doesn't handle reloads nor multiple functions
>>created through exec's.

Manlio Perillo wrote:
> No, I don't want this. "Hello!" should be printed every times.

I see.  I was writing code to emulate C's "static" behaviour
which is not what you wanted.


> Here is a functions that returns True if the caller's 'recursion
> depth' is 1.
> Please check if this is correct.

>>>>def firstlevel_call():
> 
>        return sys._getframe(1).f_code != sys._getframe(2).f_code

 > N.B.: sys._getframe(2) can raise an exception

Looks like it should work, and be thread-safe.  Again,
I don't suggest using it.  It's going to be slower than
one where you use pass the stack depth in as a parameter.
It's also going to depend on implmentation behaviour.
Someday a Python system may not instantiate the stack
information until it's requested, causing a big run-time
hit.  But that's only theoretical.

> Sorry, I don't understand.
> Here is my_function:
> 
> 
> def my_function(a, b, *args, **kwargs):
> 	print 'a, b, args, kwargs:', a, b, args, kwargs

That's not recursive, so I don't know how to
interpret your question.  Let's suppose you're
doing Ackermann's function

def Ackermann(m, n):
     if m == 0:
         return n+1
     if n == 0:
         return Ackermann(m-1, 1)
     return Ackermann(m-1, Ackermann(m, n-1))

You might want to add some parameter checking
and add some stack checking.  You can do it like this

def _Ackermann(m, n, depth):
     if not depth:
         raise AssertionError("too deep")
     if m == 0:
         return n+1
     if n == 0:
         return _Ackermann(m-1, 1, depth-1)
     return _Ackermann(m-1, _Ackermann(m, n-1, depth-1), depth-1)

def Ackermann(m, n):
     if (m < 0 or n < 0 or int(m) != m or int(n) != n):
         raise TypeError("Bad parameter")
     return _Ackermann(m, n, 20)


When I run

  print Ackermann(3,2)

I get the following

Traceback (most recent call last):
   File "<stdin>", line 28, in ?
   File "<stdin>", line 13, in Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 8, in _Ackermann
   File "<stdin>", line 7, in _Ackermann
   File "<stdin>", line 3, in _Ackermann
AssertionError: too deep

and when I run

print Ackermann(-1, -2)

I get the checking from the entry point, which is

Traceback (most recent call last):
   File "<stdin>", line 14, in ?
   File "<stdin>", line 12, in Ackermann
TypeError: Bad parameter

				Andrew
				dalke at dalkescientific.com



More information about the Python-list mailing list