views:

273

answers:

3

Is there a method that I can add to my module, which will get called when destructing the class?

Update: We have a simple class which has only static member functions and needs to clean up the database connection when unloading the module. was hoping there would be a __del__ method either for modules or classes that don't have instances?

A: 

Use the del method:

class Foo:

    def __init__(self):
        print "constructor called."

    def __del__(self):
        print "destructor called."
cartman
Be sure to read http://docs.python.org/reference/datamodel.html#object.__del__
S.Lott
__init__ is not the constructor. If you use __del__ it might be possible that the gc doesn't collect the object, so in general it is better to avoid __del__ if you can.
DasIch
__init__ is not the constructor? I am confused...
cartman
Technically, the class's __call__ is the constructor; it calls __new__. __init__ is an initializer. A bunch of really subtle distinctions.
S.Lott
Thanks S.Lott, indeed you are right.
cartman
@S.Lott No, it's not. A class is the instance of it's metaclass so if you instantiate a class you call the instance of the metaclass. So you could say that `Class.__metaclass__.__call__` is the constructor. However normally you think of `Class.__new__` as the constructor.
DasIch
+1  A: 

The class destructor method you're looking for is __del__. There are some nuances to when it's called, and to how exceptions and subclassing should be handled in __del__, so be sure to read the official docs.

A quick note on terminology, too: in python a module is the file in which your code is located... a namespace, in essence. A single module can contain many classes, variables, and functions. The __del__ method is located on the class, not on the module.

Jarret Hardie
+2  A: 

When destructing which class? I though you said module?

Your module lives until the interpreter stops. you can add something to run at that time using the "atexit" module:

import atexit
atexit.register(myfunction)


EDIT: Based on your comments.

Since you don't want it as a destructor, my answer above is correct. Just def another function (or static method if you wish) and register it with the atexit:

def close_database():
    proceed_to_close()

import atexit
atexit.register(close_database)

Now a quick note on your definition.

You said the class doesn't have any instances. So why make it a class? Why not define the functions in the module level instead? modules are first-class objects, cached and imported only once...

Example, instead of defining database.py:

class DataBase(object):
    @staticmethod
    def execute_some_query(query):
        code_here()
        some_code()
    @staticmethod
    def close_database():
        proceed_to_close()
import atexit ; atexit.register(DataBase.close_database)

and using:

from database import DataBase
DataBase.execute_some_query(query)

You could do this instead on database.py:

def execute_some_query(query):
    code_here()
    some_code()

def close_database():
    proceed_to_close()
import atexit ; atexit.register(close_database)

And use it like this:

import database
database.execute_some_query(query)


Or better yet: Use sqlalchemy and avoid all this trouble of creating your own database interface.

nosklo