[Python-Dev] recursive closures - reference cycle (original) (raw)

Kristján Valur Jónsson kristjan at ccpgames.com
Tue Dec 8 17:15:56 CET 2009


-----Original Message----- From: python-dev-bounces+kristjan=ccpgames.com at python.org [mailto:python-dev-bounces+kristjan=ccpgames.com at python.org] On Behalf Of Antoine Pitrou Sent: 8. desember 2009 14:55 To: python-dev at python.org Subject: Re: [Python-Dev] recursive closures - reference cycle

Kristján Valur Jónsson <kristjan ccpgames.com> writes: > > The problem with this is that once you have called > factorial() once, you end up with a recursive cycle. You don't need a closure to exhibit a reference cycle. A global function is enough: >>> def helper(n): ... if n: ... return n*helper(n-1) ... else: ... return 1 ... >>> helper.funcglobals['helper'] is helper True yes, because: func_globals is globals() == True

You don't need recursion for this to be true. And as soon as you delete "helper" from globals() it goes away. w = wearref.weakref(helper) del helper w() == False.

If you really want to avoid this you can prevent the function from depending on its outside environment: >>> from functools import partial >>> def helper2(rec, n): ... if n: ... return n*rec(rec, n-1) ... else: ... return 1 ... >>> factorial = partial(helper2, helper2) >>> "helper2" in factorial.func.funcglobals True >>> del helper2 >>> "helper2" in factorial.func.funcglobals False >>> factorial(3) 6

Interesting, pass itself in as an argument. Yes, there are ways around this, I know. But you have to agree that it is unexpected, no? Somethign for the "reference cycle FAQ."

Anyway, I´ll return to my lair now, thanks for your time python-dev :)

K



More information about the Python-Dev mailing list