Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: closures and classes

I need to register an atexit function for use with a class (see Foo below for an example) that, unfortunately, I have no direct way of cleaning up via a method call: other code, that I don't have control over, calls Foo.start() and Foo.end() but sometimes doesn't call Foo.end() if it encounters an error, so I need to clean up myself.

I could use some advice on closures in this context:

class Foo:
  def cleanup(self):
     # do something here
  def start(self):
     def do_cleanup():
        self.cleanup()
     atexit.register(do_cleanup)
  def end(self):
     # cleanup is no longer necessary... how do we unregister?
  • Will the closure work properly, e.g. in do_cleanup, is the value of self bound correctly?

  • How can I unregister an atexit() routine?

  • Is there a better way to do this?

edit: this is Python 2.6.5

like image 424
Jason S Avatar asked Dec 28 '10 15:12

Jason S


1 Answers

Make a registry a global registry and a function that calls a function in it, and remove them from there when necessary.

cleaners = set()

def _call_cleaners():
    for cleaner in list(cleaners):
        cleaner()

atexit.register(_call_cleaners)

class Foo(object):
  def cleanup(self):
     if self.cleaned:
         raise RuntimeError("ALREADY CLEANED")
     self.cleaned = True
  def start(self):
     self.cleaned = False
     cleaners.add(self.cleanup)
  def end(self):
     self.cleanup()
     cleaners.remove(self.cleanup)
like image 72
Rosh Oxymoron Avatar answered Sep 20 '22 09:09

Rosh Oxymoron