How to call a tidy-up method when reference to object goes out of scope?

Viewed 19

I'd like to get a reference to an object, where the reference will be relatively short-lived, and at the end of the life of the reference I want to release cached resources that the object will use to service that reference efficiently, rather than expecting the caller to remember to do this itself.

Searching around a bit I found things like class decorators, but that seems to be used in the opposite way from what I want. I want to "decorate" a reference rather than the object type itself.

I also found how to delegate attributes of an object so I can create a class that presents itself as the underlying object while having an independent __del__ method to perform clean-up. Like so:

def get_wrapped_thing(id):
  class TidyUp:
    def __init__(self, obj):
      self.__dict__['obj'] = obj
    def __getattr__(self, attr):
      return getattr(self.obj, attr)
    def __setattr__(self, attr, value):
      return setattr(self.obj, attr, value)

    def __del__(self):
      self.obj.tidyup()

  thing = get_thing(id)
  return TidyUp(thing)

I think that should work, but it feels like it's probably a bad way to go about things. Too many underscores usually makes me think I'm doing it wrong.

Is there a "pythonic" way to recognise when cached resources can be cleaned up because the reference that caused their allocation has gone out of scope?

The tidyup() method and the resource allocation methods may be different for different objects from get_thing() (some of them don't need a cache) so I can't just hoist all that caching logic into the wrapper itself.

1 Answers
import gc
del object_to_delete
gc.collect() # force-clean memory after that
Related