Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: can't invoke parent class destructor with super()

I can't invoke the destructor of the Parent class from the destructor of the Child class. Please, check the code below:

class BaseClass(object):
    def __del__(self):
        print 'BaseClass->Destructor'

class DerivativeClass(BaseClass):
    def __del__(self):
        print 'DerivativeClass->Destructor'
        #Invoke destructor of the base class, it works 
        BaseClass.__del__(self)           
        #Doesn't work
        #super(DerivativeClass, self).__del__() 

instance = DerivativeClass()

When I use super(DerivativeClass, self).__del__() in DerivativeClass.__del__() I got the following error:

Exception TypeError: 'must be type, not None' in <bound method 
DerivativeClass.__del__ of <__main__.DerivativeClass object at 0xb73a682c>> ignored

QUESTION:

Why can't I use super in the destructor of the child class while it's perfectly fine in the constructor of the child class?

like image 566
Konstantin Avatar asked Apr 09 '14 19:04

Konstantin


People also ask

Does the parent destructor get called?

Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body. Also like constructors, a child class may inherit the parent's destructor if it does not implement one itself.

Why does a class need to manually call a superclass's __ init __ method?

The main reason for always calling base class _init__ is that base class may typically create member variable and initialize them to defaults. So if you don't call base class init, none of that code would be executed and you would end up with base class that has no member variables.

How do you call a derived class destructor?

No. You never need to explicitly call a destructor (except with placement new). A derived class's destructor (whether or not you explicitly define one) automagically invokes the destructors for base class subobjects. Base classes are destructed after member objects.

Does Python automatically call super init?

Basically, super-class delegation of the initializer is not automatic in Python for exactly the same reasons such delegation is also not automatic for any other methods -- and note that those "other languages" don't do automatic super-class delegation for any other method either... just for the constructor (and if ...


1 Answers

It seems that this happens only on runtime exit (because DerivativeClass is None).

This works fine:

class BaseClass(object):
    def __del__(self):
        print 'BaseClass->Destructor'

class DerivativeClass(BaseClass):
    def __del__(self):
        print 'DerivativeClass->Destructor'
        super(DerivativeClass, self).__del__() 

instance = DerivativeClass()
del instance

And this works fine too:

class BaseClass(object):
    def __del__(self):
        print 'BaseClass->Destructor'

class DerivativeClass(BaseClass):
    def __del__(self):
        print 'DerivativeClass->Destructor'
        super(type(self), self).__del__() 

instance = DerivativeClass()

Also this:

class BaseClass(object):
    def __del__(self):
        print 'BaseClass->Destructor'

class DerivativeClass(BaseClass):
    def __del__(self):
        print 'DerivativeClass->Destructor'
        super(DerivativeClass, self).__del__() 

def someScope ():
    instance = DerivativeClass()

someScope ()

In snippets 1 and 3, I make sure that the instance dies before the class. In snippet 2 I circumnavigate the whole issue in quite an ugly manner.

like image 144
Hyperboreus Avatar answered Sep 24 '22 15:09

Hyperboreus