Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python destructors in new and old style classes [duplicate]

I'm trying to understand why object destruction works differently in new style classes compared to old style ones.

class Wrapper():
    class Inner(object):
        def __del__(self):
            print 'Inner destructor'

    innerInstance = Inner()

    def __del__(self):
        print 'Wrapper destructor'

if __name__ == '__main__':
    x = Wrapper()

on exit, this will output:

Wrapper destructor
Inner destructor

however, if i use Wrapper as a new style class, only the wrapper destructor is called, and the output is:

Wrapper destructor

Could someone explain the behavior shown above ?

like image 269
Alexander Pope Avatar asked Oct 06 '22 08:10

Alexander Pope


1 Answers

The python data model explicitly states:

It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits.

In this case, a Wrapper (class and instance) object still exists when the interpreter exits, so there is no guarantee that it will be finalized. And even though we see that the Wrapper instance is finalized, there is no gurarantee that the Wrapper class will be finalized (which is what is holding your Inner instance).


As a side note, if I run this code with Jython, __del__ isn't called for either object (regardless of whether we're using old-style or new-style classes). Suprisingly, It doesn't even work (with Jython) if I explicitly delete the objects (but this code does work with CPython, regardless of old-style/new-style):

class Wrapper():
    class Inner(object):
        def __del__(self):
            print 'Inner destructor'

    innerInstance = Inner()

    def __del__(self):
        print 'Wrapper destructor'

if __name__ == '__main__':
    print "foo"
    x = Wrapper()
    print "bar"
    del x
    del Wrapper
like image 199
mgilson Avatar answered Oct 10 '22 03:10

mgilson