[Tutor] Object Destruction

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Wed, 24 Jan 2001 22:34:05 -0800 (PST)

On Wed, 24 Jan 2001, Gregg T. Geiger wrote:

> What are scope rules for class objects and when are they
> destroyed, specifically with regards to for loops?
> That is, if a class Spam is defined somewhere and used in a
> for loop as follows:
> for i in [0, 1, 2, 3, 4]:
>   spam = Spam()
>   # end of for loop

Hmm... Python is reference garbage collected, so whenever an instance's
reference count goes to zero, the instance should implode. We can
experimentally test to see when an object gets garbage collected by
overriding the '__del__' method.  Since Python works well with the
interpreter, let's try it out:

>>> class TestDel:
...     def __init__(self, name):
...         self.name = name
...     def __del__(self):
...         print self.name, "garbage collected"
>>> TestDel("Anna")
<__main__.TestDel instance at 0x81ca2fc>  

# that's curious, I expected garbage collection at this point... Strange!
# I'll have to think about that one later...

>>> x = TestDel("Anna")
>>> del(x)
Anna garbage collected
>>> x = TestDel("Anna")
>>> x = TestDel("King")
Anna garbage collected
>>> for i in range(5):
...     x = TestDel(i)
King garbage collected
0 garbage collected
1 garbage collected
2 garbage collected
3 garbage collected

So it pretty much does what you'd expect... except for that odd thing at
the very beginning.  Weird!

> will an object be created and destroyed with each pass
> through the loop or does each instance remain "alive"?  In
> a comparable C++ loop

>From the results above, yes.

> the destructor is called 5 times.  In my own experience
> with Python, files opened in Spam are not closed each time
> through the loop unless explicitly closed within the class.

Those files have to go out of scope, so that the reference counts go
down; otherwise, Python might prematurely close things down.  If you want,
you can show us the file opening code, and we can make sure that things
look ok.

Try some more experiments with __del__.  I'm somewhat bothered by what
happened at the beginning of the interpreter session above, and might take
a look again later to figure out why it didn't garbage collect initially.