On Jul 9, 7:30 pm, Lie Ryan <lie.1...@gmail.com> wrote: > brasse wrote: > > Hello! > > I have been thinking about how write exception safe constructors in > > Python. By exception safe I mean a constructor that does not leak > > resources when an exception is raised within it. The following is an > > example of one possible way to do it: > > First, your automatic cleaning Bar() silently pass an unitialized Bar() > into the calling code. When a code fails, it should fail as loud as > possible. Bar() should raises an Exception and the calling code should > turn into something like: > > try: > bar = Bar() > except Exception, e: > print 'bar failed to construct' >
I know, I missed that little detail. :-) > And about the cleaning up, how about: > > class CleanWrap(object): > def __init__(self, cls, cleanup): > self.cls = cls > self.cleanup = cleanup > def __call__(self, *args, **kargs): > try: > return self.cls(*args, **kargs) > except: > self.cleanup() > raise > > class Bar(object): > def __init__(self): > CleanWrappedFoo = CleanWrap(Foo, self.close) > self.a = CleanWrappedFoo('a') > self.b = CleanWrappedFoo('b', fail=True) > def close(self): > if hasattr(self, 'a'): > self.a.close() > if hasattr(self, 'b'): > self.b.close() > I think this example adds about as much overhead as my original example with the try block. Ideally I would like to be able to write my classes in the most straight forward manner possible. In my mind that would be something like a naive constructor and a close/dispose method: def __init__(self): self.a = Foo() self.b = Bar() def close(self): self.a.close() self.b.close() See my other post (the one with the decorator named safe) in this thread for an experiment I thought was promising for a while. However there are some some use cases it has to cover to be useful: (1) References to objects owned by someone else def __init__(self, some_resource): self.not_my_responsibility = some_resource self.a = Foo() # If Foo.__init__ raises an exception self.not_my responsibility should not be closed. (2) Local objects def __init__(self): x = Bar() self.a = Foo(x) # If Foo.__init__ raises an exception x should also be closed. So far I have not been able to find any good solutions for (at least) case 1. I'll give it a few more days, but I'm not that hopeful. I think that I will end up writing my classes very much like Bar in my original post. If someone has any ideas for how to solve my two use cases above with my decorator based approach I would really like to hear them! :.:: mattias -- http://mail.python.org/mailman/listinfo/python-list