Deletion order when leaving a scope?
I just ran a quickie experiment and determined: when leaving a scope, variables are deleted FIFO, aka in the same order they were created. This surprised me; I'd expected them to be deleted LIFO, aka last first. Why is it thus? Is this behavior an important feature or an irrelevant side-effect? Cheers, /larry/
Larry Hastings
I just ran a quickie experiment and determined: when leaving a scope, variables are deleted FIFO, aka in the same order they were created. This surprised me; I'd expected them to be deleted LIFO, aka last first. Why is it thus? Is this behavior an important feature or an irrelevant side-effect?
If you are talking about the locals in the scope of a function, it is an artifact of how the locals array is created. That is to say, the locals of a function are a flat array, and are decref'd in-order. That ordering is the original assignment ordering in the function, which is an artifact of how the compiler goes from local name -> FAST_LOCALS index. I don't believe it is an "important feature", but to decref in any other order would be silly and/or unintuitive. - Josiah
On 1/18/07, Larry Hastings
I just ran a quickie experiment and determined: when leaving a scope, variables are deleted FIFO, aka in the same order they were created. This surprised me; I'd expected them to be deleted LIFO, aka last first. Why is it thus? Is this behavior an important feature or an irrelevant side-effect?
Please regard it as an irrelevant side-effect. If you want objects to be
cleaned up in a particular order, you should enforce it by having one of
them refer to the other. A great many details can affect the order in which
variables are cleaned up, and that only decreases refcounts of the actual
objects -- a great many other details can then affect the order in which any
objects left with a 0 refcount are actually cleaned up. Even not counting
the more complicated stuff like GC and funky __del__ methods, just having
'import *' or a bare 'exec' in your function can change the order of
DECREFs.
--
Thomas Wouters
Thomas Wouters wrote:
On 1/18/07, *Larry Hastings*
mailto:larry@hastings.org> wrote: I just ran a quickie experiment and determined: when leaving a scope, variables are deleted FIFO, aka in the same order they were created. This surprised me; I'd expected them to be deleted LIFO, aka last first. Why is it thus? Is this behavior an important feature or an irrelevant side-effect?
Please regard it as an irrelevant side-effect. If you want objects to be cleaned up in a particular order, you should enforce it by having one of them refer to the other. A great many details can affect the order in which variables are cleaned up, and that only decreases refcounts of the actual objects -- a great many other details can then affect the order in which any objects left with a 0 refcount are actually cleaned up. Even not counting the more complicated stuff like GC and funky __del__ methods, just having 'import *' or a bare 'exec' in your function can change the order of DECREFs.
I imagine this would be important to someone expecting system resources to be cleaned up, closed, deallocated, or returned inside of __del__ methods. Someone coming from C++ might expect LIFO behavior because common idioms like RAII (Resource Allocation Is Instantiation) don't work otherwise. A Java programmer wouldn't care, being used to cleaning up resources manually with a try...catch...finally. I'm just putting a possible motivation on the concern. It happens that the Pythonic Way is also the Java Way in this area: don't expect any specific deletion order (don't even expect a guaranteed call to __del__), and manually clean up after yourself. As a warning, this has been the subject of a great many flame wars between C++ and Java programmers... Neil
Neil Toronto wrote:
I imagine this would be important to someone expecting system resources to be cleaned up, closed, deallocated, or returned inside of __del__ methods. Someone coming from C++ might expect LIFO behavior because common idioms like RAII (Resource Allocation Is Instantiation) don't work otherwise. A Java programmer wouldn't care, being used to cleaning up resources manually with a try...catch...finally.
I'm just putting a possible motivation on the concern. It happens that the Pythonic Way is also the Java Way in this area: don't expect any specific deletion order (don't even expect a guaranteed call to __del__), and manually clean up after yourself. As a warning, this has been the subject of a great many flame wars between C++ and Java programmers...
We know. Python 2.5 added a new statement (with) and a new standard library module (contextlib) to allow resource deallocation to be dealt with cleanly without requiring assumptions about the interpreter's memory model. While RAII isn't mentioned explicitly in the corresponding PEP (PEP 343), it was certainly a factor in the python-dev discussions. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
Nick Coghlan
Neil Toronto wrote:
I imagine this would be important to someone expecting system resources to be cleaned up, closed, deallocated, or returned inside of __del__ methods. Someone coming from C++ might expect LIFO behavior because common idioms like RAII (Resource Allocation Is Instantiation) don't work otherwise. A Java programmer wouldn't care, being used to cleaning up resources manually with a try...catch...finally.
I'm just putting a possible motivation on the concern. It happens that the Pythonic Way is also the Java Way in this area: don't expect any specific deletion order (don't even expect a guaranteed call to __del__), and manually clean up after yourself. As a warning, this has been the subject of a great many flame wars between C++ and Java programmers...
We know. Python 2.5 added a new statement (with) and a new standard library module (contextlib) to allow resource deallocation to be dealt with cleanly without requiring assumptions about the interpreter's memory model.
While RAII isn't mentioned explicitly in the corresponding PEP (PEP 343), it was certainly a factor in the python-dev discussions.
It's mentioned in PEP 310, the predecessor to PEP 343. Cheers, mwh -- "I lacked the courage to investigate the weaknesses of the wicked, because I discovered they are the same as the weaknesses of the saintly." -- The Name Of The Rose, Umberto Eco
Larry Hastings schrieb:
I just ran a quickie experiment and determined: when leaving a scope, variables are deleted FIFO, aka in the same order they were created.
Your experiment was apparently incomplete: Variables are *not* deleted in the same order in which they are created: py> class A: ... def __init__(self, n):self.n = n ... def __del__(self): print "Deleting", self.n ... py> def f(x): ... if x: ... a = A("a") ... b = A("b") ... else: ... b = A("b") ... a = A("a") ... py> f(0) Deleting a Deleting b Here, it creates b first, then a (it's the else case), yet deletes them in reverse order. As others have pointed out, the deletion order is the one indicated by the locals array: py> f.func_code.co_varnames ('x', 'a', 'b') Regards, Martin
participants (7)
-
"Martin v. Löwis"
-
Josiah Carlson
-
Larry Hastings
-
Michael Hudson
-
Neil Toronto
-
Nick Coghlan
-
Thomas Wouters