First, I wrote a recording class with a flush method:
class Recorder
def __init__(self, buffer_size, path):
self._big_buffer = np.array(*buffer_size)
self._path = path
def push(self, data):
# insert in self._big_buffer
# if self._big_buffer is full:
# self._flush()
def flush(self):
# write buffer to disk (self._path)
Then, I wanted to flush at exit: when manually stopped, crashed or whatever reason.
So I used:
def __init__(self):
(...)
atexit.register(self.flush)
And it worked pretty well.
But now, I want to record, stop recording, record again, multiple times, with a different buffer size and to a different path. So I have to discard, then instanciate several Recorder
. It kind of works, but older Recorder
's memory (containing some fat self._big_buffer̀
) is not freed since it's retained by atexit
. Even when I explicitly call del
.
I can't atexit.unregister(self._flush)
since it's Python 3 only.
I would prefer not to reuse existing instances, but discarding older instances and create new ones.
How would you handle such a case?
You can try using a weak reference to the atexit
handler, so the object
won't be retained if it is deleted elsewhere:
import atexit
import weakref
class CallableMethodWeakRef:
def __init__(self, object, method_name):
self.object_ref = weakref.ref(object)
self.method_name = method_name
def __call__(self):
object = self.object_ref()
if object:
getattr(object, self.method_name)()
class Recorder:
def __init__(self, *args):
atexit.register(CallableMethodWeakRef(self, 'flush'))
def flush(self):
print 'flushing'
The method is passed as a string in order to avoid a lot of problems with
bound method weak references, if you find it disturbing you can always use
a BoundMethodWeakref
implementation like this one: http://code.activestate.com/recipes/578298-bound-method-weakref/