Douglas Alan wrote: > Lenard Lindstrom <[EMAIL PROTECTED]> writes: > >> Douglas Alan wrote: > >>> [I]n Python, you can be 100% sure that your files >>> will be closed in a timely manner without explicitly closing them, as >>> long as you are safe in making certain assumptions about how your code >>> will be used. Such assumptions are called "preconditions", which are >>> an understood notion in software engineering and by me when I write >>> software. > >> So documenting an assumption is more effective than removing the >> assumption using a with statement? > > Once again I state that I have nothing against "with" statements. I > used it all the time ages ago in Lisp. >
Sorry if I implied that. I assumed it would be clear I was only referring to the specific case of implicitly closing files using reference counting. > But (1) try/finally blocks were not to my liking for this sort of > thing because they are verbose and I think error-prone for code > maintenance. I and many others prefer relying on the refcounter for > file closing over the try/finally solution. Consequently, using the > refcounter for such things is a well-entrenched and succinct idiom. > "with" statements are a big improvement over try/finally, but for > things like file closing, it's six of one, half dozen of the other > compared against just relying on the refcounter. > I agree that try/finally is not a good way to handle resources. > (2) "with" statements do not work in all situations because often you > need to have an open file (or what have you) survive the scope in > which it was opened. You may need to have multiple objects be able to > read and/or write to the file. And yet, the file may not want to be > kept open for the entire life of the program. If you have to decide > when to explicitly close the file, then you end up with the same sort > of modularity issues as when you have to free memory explicitly. The > refcounter handles these sorts of situations with aplomb. > Hmm. I come from a C background so normally don't think of a file object as leading a nomadic life. I automatically associate a file with a home scope that is responsible for opening and closing it. That scope could be defined by a function or a module. But I'm not a theorist so can't make any general claims. I can see, though, how ref count could close a file sooner than if one waits until returning to some ultimate enclosing scope. > (3) Any code that is saving tracebacks should assume that it is likely > to cause trouble, unless it is using code that is explicitly > documented to be robust in the face of this, just as any code that > wants to share objects between multiple threads should assume that > this is likely to cause trouble, unless it is using code that is > explicitly documented to be robust in the face of this. > Luckily there is not much need to save tracebacks. > (4) Any code that catches exceptions should either return soon or > clear the exception. If it doesn't, the problem is not with the > callee, but with the caller. > Explicitly clear the exception? With sys.exc_clear? > (5) You don't necessarily want a function that raises an exception to > deallocate all of its resources before raising the exception, since > you may want access to these resources for debugging, or what have you. > No problem: >>> class MyFile(file): def __exit__(self, exc_type, exc_val, exc_tb): if exc_type is None: file.__exit__(self, None, None, None) return False >>> del f Traceback (most recent call last): File "<pyshell#36>", line 1, in <module> del f NameError: name 'f' is not defined >>> try: with MyFile("something", "w") as f: raise StandardError("") except StandardError: print "Caught" Caught >>> f.closed False But that is not very imaginative: >>> class MyFile(file): def __exit__(self, exc_type, exc_val, exc_tb): if exc_type is not None: self.my_last_posn = self.tell() return file.__exit__(self, exc_type, exc_val, exc_tb) >>> del f Traceback (most recent call last): File "<pyshell#44>", line 1, in <module> del f NameError: name 'f' is not defined >>> try: with MyFile("something", "w") as f: f.write("A line of text\n") raise StandardError("") except StandardError: print "Caught" Caught >>> f.closed True >>> f.my_last_posn 16L --- Lenard Lindstrom <[EMAIL PROTECTED]> -- http://mail.python.org/mailman/listinfo/python-list