On Wed, 9 Sep 2009 15:13:49 -0700 (PDT), r <rt8...@gmail.com> wrote: >On Sep 9, 4:19 pm, Charles Yeomans <char...@declaresub.com> wrote: >(snip:) >> Unfortunately, both of these simple templates have the following >> problem -- if open fails, a NameError will be raised from the finally >> block. > >(snip) >> I removed the except block because I prefer exceptions to error codes. > >how will the caller know an exception has occurred? What if logic >depends on the validation that a file *had* or *had not* been written >too, huh? > >> In addition to fixing the latent bug in the second simple template, I >> took the opportunity to correct your heinous violation of command- >> query separation. >> >> Charles Yeomans > >Oh I see! But what happens if the filename does not exist? What then? >"open" will blow chucks thats what! Here is a version for our paranoid- >schizophrenic-sadomasochist out there...
Well first, we agree that putting the open() in the try part of a try-finally is wrong. try-finally is supposed to ensure that _allocated_ resources are cleaned up. What you do below may work. But it's essentially throwing out exception handling and using error codes instead. There are plenty of reasons why exceptions are preferred. The standard thing is this: def UseResource(rname): r = get(rname) try: r.use() finally r.cleanup() Now if the get() fails, UseResource will indeed blow chunks. That's what it _should_ do. Generally speaking, you should use try-except very rarely, making certain you're catching the exception at the appropriate level. Here for example in _some_ uses of UseResource() you _want_ the application to terminate if the get() fails. In that case you'd just call UseResource() without any try-excpt. In some other situation (maybe the user provided a filename that may or may not exist) you want to trap the exception when you _call_ UseResource(): try: UseResource(rname) except WhateverError: print error message >def egor_read_file(fname, mode='rb'): > print 'yes, master' > try: > f = open(fname, mode=mode) > except IOError: > return (0, 'But, the file no open master!') > > try: > s = f.read() > except NameError: > return (0, 'the file still no open master!') > > try: > f.close() > except: > print 'That file sure is tricky master! > > return (s, 'Whew! here is the file contents, master') What's above seems simpler. More important, if you do it this way then you _always_ have to check the return value of egor_read_file and take appropriate action - complicates the code everywhere the function is called as well as making the function more complicated. Doing it as in UseResource() above you don't need to worry about whether UseResource() failed _except_ in situations where you're certain that that's the right level to catch the error. > >> MRAB wrote: >> You should've used raw strings. :-) > >rats!, you got me on that one :-) David C. Ullrich "Understanding Godel isn't about following his formal proof. That would make a mockery of everything Godel was up to." (John Jones, "My talk about Godel to the post-grads." in sci.logic.) -- http://mail.python.org/mailman/listinfo/python-list