getrecursiondepth
Andrew Dalke
adalke at mindspring.com
Tue Sep 28 12:26:16 EDT 2004
Manlio Perillo wrote:
>>>1) To write code that execute once in a function (as C static
>>>variables)
>>>2) To guard against too many recursion
> def spam(x):
> if getrecursiondepth() == 1:
> # initialization code
>
> This is equivalent to C++ code:
>
> struct Init
> {
> Init() { /* initialization code */ }
> };
>
> void spam(int x)
> {
> static Init init;
> ...
> }
No, it isn't. It requires that spam() be called from
the top-level code. But what if it's called from
the unittest framework? Then the depth will be lower.
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.
_firsttime_db = {}
def firsttime():
frame = sys._getframe(1)
tag = (frame.f_lineno, frame.f_code.co_filename)
if tag in _firsttime_db:
return 0
_firsttime_db[tag] = 1
return 1
>>> def spam():
... if firsttime():
... print "Hello!"
... print "called"
...
>>> spam()
Hello!
called
>>> spam()
called
>>> spam()
called
>>>
You could make it a bit safer with
import weakref
_firsttime_dict = weakref.WeakKeyDictionary()
def firsttime(obj):
if obj in _firsttime_dict:
return 0
_firsttime_dict[obj] = 0
return 1
def spam():
if firsttime(spam):
print "Hello"
print "called"
> I have already used this 'pattern'.
> But sometimes I don't want to expose the 'limit' on the argument list.
> Actually I have resolved this by doing:
>
> def my_function(x, y, z, __max_depth = 20)
>
> But this means I can't use keyword argument in my function!
then do
def _my_function(x, y, z, __maxdepth = 20):
.. do your recursive code here ..
def my_function(x, y, z):
return _my_function(x, y, z)
How would you solve this problem using your stack depth
function? Any solution I come up with is more
complicated than what I just showed here and is no
longer thread safe.
> This is not a problem!.
> getrecursiondepth is not intended for such things.
...
> Ok, but remember the Python paradigm: we are adult programmers...
As an adult I still don't know what you would want
to use this value. The first example you give
(static init) fails if someone looks at it funny.
I'm adult, but I can't be that cautious. The second
example (recursion), well I just don't see how knowing
the depth makes the code any easier to write or clearer
to understand.
> Anyway I have asked why getrecursiondepth is not included in sys
> module because many members of the PyThreadState struct are accessible
> from Python.
Maybe they're useful?
Andrew
dalke at dalkescientific.com
More information about the Python-list
mailing list