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
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com