It seems object cleanup is a pretty common problem I've encountered during my programing days. To date I have consistently used the with
statement as recommended here
I had another thought today which seems more elegant to me (because it does not require a with statement by the end user). The idea would be to use a try-finally decorator for objects of a certain type (have a cleanup method).
Just wondering if there is anything wrong with this practice or if there is something even better. I don't like that many of my classes need to be initialized using a with statement, but I also want to ensure my objects are closed properly. Here's a short example.
def cleanme(func):
def _decorator(self, *args, **kwargs):
try:
func(self, *args, **kwargs)
finally:
self._cleanup()
return _decorator
class IObject(object):
def __init__(self):
self.file_name = "some_file.txt"
self._file_object = None
self._cleaned = True
@cleanme
def run(self):
self._connect()
while True:
# do some things over a long period
pass
def _connect(self):
self._file_object = open(self.file_name)
self._cleaned = False
def _cleanup(self):
if not self._cleaned:
self._file_object.close()
self._cleaned = True
Let me shoot a couple of holes in this.
One thought, you're obliging your classes to have a cleanup()
, which is declared not in a place different from run()
. So you're imposing a user's responsibility to implement and maintain it cleanly.
Destructors other than __exit__
are pretty uncommon in Python, so the resource acquisition code may drift from cleanup()
code, imposing a leak.
Second, you're making file_object
an instance variable, thus widening its scope from a single function, which is also somewhat bad.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With