This question already has an answer here:
-
Why do new style class and old style class have different behavior in this case?
1 answer
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 ?
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