Re: Deleting an object within itself.

Steven D. Majewski (sdm7g@elvis.med.virginia.edu)
Wed, 27 Jul 1994 17:43:38 -0400

'del' does different things, depending: 'del a[3:6]' is rather
different than 'del a'. 'del' is a python statement, not a function
(like 'import' ) and if you peek at the ceval.c code, or you
decompile some .pyc code, you will see that those two examples
compile into different code.

( FYI: the different possible cases are:

case DELETE_SLICE+0:
case DELETE_SUBSCR:
case DELETE_NAME:
case DELETE_ATTR:
case DELETE_GLOBAL:
case DELETE_FAST:
)

But in general, for the type of thing you are trying to do, basically
'del' does a decrement of the reference counter for that object, and
the destructor function ( in this case method __del__ ) does not get
called until that reference count goes to zero.

To get more pedantic about it, what you are realling deleting with
'del' is a NAME binding, and the *OBJECT* is only deleted when there
are no more names to it.

>>> class Test:
... def __init__( self ): print 'Hello', self
... def __del__( self ) : print 'Goodybe', self
...
>>> a = Test()
Hello <Test instance at 20067e78>
>>> del a
Goodybe <Test instance at 20067e78>
>>> a = Test()
Hello <Test instance at 20067dc8>
>>> b = a
>>> a
<Test instance at 20067dc8>
>>> del a # NOTE that nothing happens because there is still a
# name (b) referring to <Test instance at 20067dc8>
>>> b
<Test instance at 20067dc8>
>>> del b
Goodybe <Test instance at 20067dc8>
>>>

In your example, "self" and "h" are two different names in two
different scopes that both ( at particular times in program
execution ) refer to the same object.

So, to take you literally:

>Subject: Re: Deleting an object within itself.
> In short, how do you do it?

In short: you can't!
(Python was designed to make it impossible to have dangling references.)

So the obvious question is: why would you want to ?

Note that in your example, the name "h" is local to function
"test", so as soon as test exits, the name h is deleted and
since that particular instance of the object no longer has
an existing reference, the object is deleted.

You can explicitly call the '__del__' method, but that doesn't
'del' the object. But if your expect to explicitly call your
__del__ function, then maybe it shouldn't be *called* "__del__".
Consider objects like sockets and files ( and similar user
written classes ) where there is an explicit close() method,
which closes the file or connection, but keeps the object
in existance, and an implicit destructor method which will
call the close method before the object goes away. This is
typically the sort of behaviour you want. ( In my IMAP routines,
I even had a 'reopen' method which reactivates a closed connection:
I may add support to automatically reopen timed out connections, but
it was in there mainly because other classes ( mailboxes and messages )
keep a reference to the IMAP session, which just might have been
closed without the "downstream" objects knowing about it. But it's
would also be possible (ignoring timeouts for the moment) to cross
link the classes in a way ( probably by hiding the close method and
using __del__ ) so that it was impossible to close a connection which
had "live" references. )

-- Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> --
-- UVA Department of Molecular Physiology and Biological Physics --
-- Box 449 Health Science Center Charlottesville,VA 22908 --
[ Back from the beach, rested, tan, and ready to Python! ]

On Jul 27, 18:08, "Michael Kuperstein - EECS (CPTS317)" wrote:
>
> In short, how do you do it?
>
>
> Here is the program:
>
> class Hello:
> def __init__( self ):
> print 'Hello.__init__() called'
>
> def __del__( self ):
> print '__del__ called'
>
> def hi( self ):
> print 'Hi there!'
>
> def Delete( self ):
> del self
>
> def test():
> print 'instantiating h'
> h = Hello()
> print 'deleting h'
> h.Delete
> print 'accessing h'
> h.hi()
> print 'exiting test()'
>
>
> And here is the output:
>
> dryden% python
> Python 1.0.2 (Jun 21 1994)
> Copyright 1991-1994 Stichting Mathematisch Centrum, Amsterdam
> >>> import delete
> >>> delete.test()
> instantiating h
> Hello.__init__() called
> deleting h
> accessing h
> Hi there!
> exiting test()
> __del__ called
> >>>
>