On Aug 5, 5:23 am, Terry Reedy <[EMAIL PROTECTED]> wrote:

> To understand this, it helps to realize that Python functions are not,
> in themselves, recursive.  Recursiveness at any time is a property of a
> function in an environment, which latter can change.  More specifically,
> a function call is recursive if the expression indicating the function
> to call happens to indicate the function containing the call at the time
> of evaluation just before the evaluation of the argument expressions.

I didn't realize that the function looks up itself in the outer
environment when it makes the recursive call, instead of at definition
time.

> Adding 'inner = None' at the end of an outer function will break the
> cycle and with CPython, all will be collected when outer exits.

I think I'll use that for inner functions that do need to access the
outer environment, but do not need to live longer than the call to the
outer function.

> Not a bug, but an educational example and possibly useful to someone
> running on CPython with gc turned off and making lots of calls to
> functions with inner functions with recursive references.  I learned a
> bit answering this.

That describes our application: in some cases, we have several
gigabytes of small objects, in which case mark-and-sweep garbage
collection takes quite a long time, especially if some of the objects
have been pushed into the swap. I have broken all cycles in our own
data structures a while ago, but got an unexpected memory leak because
of these cyclic references from inner functions.

Thanks for your clear explanation!

Bye,
        Maarten
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to