Hello there.

Consider this code:

def factorial(n):
                def helper(n):
                               if n:
                                               return n*helper(n-1)
                               else:
                                               return 1
                return helper(n)

Ok, this is a bit contrived, but there are other valid reasons for calling a 
closure recursively.
The problem with this is that once you have called factorial() once, you end up 
with a recursive cycle.  "factorial" has become a cell object, referencing the 
"helper" function, which again refers to the outer cell object.  This requires 
"gc" to clean up.  Also, it is entirely non-obvious.  the problem becomes worse 
if the inner function also refers to some large, temporary variable, since it 
will get caught up in the reference loop.

A workaround is this.  Replace the final line with:
                try:
                               return helper(n)
                finally:
                                helper = None


This clears the cell before function exit.  Note that it is not possible to 
"del" it, you get a syntax error for that.

Now, the reason I'm posting this here, and not to python-lang, is this:  Is 
there a way to implement  this differently so that this pattern doesn't result 
in a cycle?
Possible ideas would be:

1)      clear "helper" on function exit.  Not good if the internal function is 
exported, though.

2)      Use have 'helper' store a weakref to the cell object

Cheers,
Kristján
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to