Cleanup Actions [SOLVED]


I need to run some cleanup code that will get executed when Panda exits (no matter how the exiting occurs). The cleanup code is related to terminating a subprocess that began earlier.

In the code below I’m printing test strings in places where I think that my custom cleanup code can go, but surprisingly these string don’t get printed, so I’m kind of confused as to where this cleanup code must be placed.

import direct.directbase.DirectStart

class Test(object):
    def __init__(self):
        print "__init__"
        # Create the subprocess here

    def __del__(self):
        print "__del__"
        # Terminate the subprocess here

    def run(self):
        print "before Test::run"
        print "after Test::run"
        # Or terminate the subprocess here

if __name__ == "__main__":
    t = Test()

    print "before run"
    print "after run"
    # Or terminate the subprocess here

Personally I would prefer to call the cleanup code in del, rather than calling it after Panda’s run() (whether is called directly or from inside Test::run()).

Isn’t del supposed to be called when the program exits (as the destructor in C++)?

Why isn’t the code after Panda’s run() getting executed?


hm… dunno if it works the way you approached the problem.
a way which does work for me is using python’s subprocess modul to start your panda-application. this would result in 2 seperated threads. and when pande gets closed, you’ll get a return value for the initial script which started panda.

You can assign a function object to base.exitFunc (note the case: you must use base.exitFunc, not base.exitfunc–there exists a base.exitfunc, but it’s something different and shouldn’t be messed with).

Whatever function you assign to base.exitFunc will be called when Panda is shut down. If you have lots of functions to call, assign this to a function that calls your entire laundry list of cleanup functions.

Python destructors are not automatically called when you exit Python–it simply exits. The code following run() is not called either, because Panda doesn’t return from run()–it simply exits.


Great! Thanks for the replies!

I’ve tested assigning a cleanup method to base.exitFunc and it works perfectly, except for when I exit my game by pressing “Escape”, after having called this:

self.accept("escape", exit)

Is exit the right function to call for terminating Panda?

Or does this means that I should create another method in which I call my custom clean cup code before calling exit, and then assigning this method to “escape”? Something like this:

def __init__(self):
    self.accept("escape", self.exit)
def exit(self):
    # Execute cleanup actions

    # Exit the game


Oh, sorry, my mistake. You can call base.userExit() instead of sys.exit() in order to call your exitFunc.

But, there’s a better answer. Instead of assigning base.exitFunc, add your function to the list in base.finalExitCallbacks. These functions will be called when you exit via sys.exit(), or via any other mechanism.

In fact, just forget what I said about base.exitFunc.


I’ve tried to access the list base.finalExitCallbacks but I get a Python error telling me that ShowBase instance has no attribute ‘finalExitCallbacks’.

Trying to access a list named “finalExitCallbacks”, that belongs to base, is what you meant when saying


Ah, oops, again I strike out.

That is what I’d meant, but it turns out that base.finalExitCallbacks is too new for Panda3D 1.6.2. It will be in 1.7.0.

In the meantime, you can use base.exitFunc, and call base.userExit() to quit.


Great! Thanks David!