Messing with the GC

Jens Thoms Toerring jt at toerring.de
Sat Jan 19 09:47:16 EST 2013


Hi,

   triggered by some problems I had with PySide I got a bit
confused about what the GC may do in certain situations.
Here's a small test program I cobbled together:

import sys

class X( object ) :
    def __init__( self, parent, cnt ) :
        print( "In constructor for {0} {1}".format( self, cnt ),
               file = sys.stderr )
        self.parent = parent
        self.cnt = cnt

    def __del__( self ) :
        print( "In destructor for {0} {1}".format( self, self.cnt ),
               file = sys.stderr )

    def foo( self ) :
        print( "Before", file = sys.stderr )
        self.parent.z = X( self.parent, 2 )     # Is this bad?
        print( "After", file = sys.stderr )

class Y( object ) :
    def __init__( self ) :
        print( "In constructor for {0}".format( self ),
               file = sys.stderr )
        self.z = X( self, 1 )

    def __del__( self ) :
        print( "In destructor for {0}".format( self ),
               file = sys.stderr )

Y( ).z.foo( )

Have a look at the line with the comment. At this point the
only reference in existence to the X class instance, of which
a method is just being executed, goes out of scope. Thus I
would assume that the GC could now kick any time, possibly
even before the following call of print() or before the method
call returns. That, in turn might result in a crash of the
script.

Is my assumption about this flawed and there are no potential
dangers? Perhaps with

Y( ).z.foo( )

a temporary second reference is created that keeps the GC
for removing the X instance...

Another thing I'm puzzled about is the output of the
script:

In constructor for <__main__.Y object at 0x2919210>
In constructor for <__main__.X object at 0x2919310> 1
Before
In constructor for <__main__.X object at 0x2919350> 2
After
In destructor for <__main__.X object at 0x2919310> 1

Ok, the destrucor for the first instance of the X class is
called only after printing out "After", so the GC didn't
delete the object before. But then there are obviously no
calls of the destructors of neither the second instance
of the X class nor of the Y class instance. Shouldn't
they be invoked before the program ends?

                Thanks and best regards, Jens
-- 
  \   Jens Thoms Toerring  ___      jt at toerring.de
   \__________________________      http://toerring.de



More information about the Python-list mailing list