The Cost of Dynamism (was Re: Pyhon 2.x or 3.x, which is faster?)

Chris Angelico rosuav at gmail.com
Tue Mar 22 10:31:37 EDT 2016


On Wed, Mar 23, 2016 at 1:02 AM, BartC <bc at freeuk.com> wrote:
>> Note, though, that "deal with" really means "deal with", and NOT
>> "print oops to the console and terminate". If all you're going to do
>> with an exception is print and terminate, *let it go*, unless it's a
>> user-triggered failure, in which case you catch it right at the very
>> highest level, and basically fall off the end of your program. The
>> number of times you have sys.exit() in an except clause should be
>> vanishingly small.
>
>
> So code like the following is consigned to history?
>
>  while 1:
>  |   file = input ("Filename (press enter to quit)? ")
>  |   if file == "": break
>  |   print ("Trying to open:",file,"...")
>  |   s = readstrfile(file)
>  |   if s != 0:
>  |   |   print ("   ",file,"has",len(s),"characters")
>  |   else:
>  |   |   print ("   There was a problem opening:",file)
>
> (Oops, ignore the bars.)

Your "else" clause there conceals the fact that it's actually
*recovering* from an error condition, by reporting it and then
returning to the main loop. So here's how I'd write it:

while "moar files":
    filename = input("Filename (blank to quit): ")
    if not filename: break
    print("Reading %s..." % filename, end="\r")
    try:
        print("   %s has %d characters." % (filename, len(readfile(filename))))
    except (IOError, OSError) as e:
        print("   Cannot read %s: %s" % (filename, e))

Aside from a few trivial changes to names and text strings and such,
the one significant change is that I catch just two types of error
(I/O and OS), and *I print out the error message*. In this case, the
traceback wouldn't be very helpful, so it's dropped; but the text
message is useful *to the user*, not just the programmer. If I were
using a program like this and it didn't distinguish between "file not
found", "permission denied", "is a directory", and "disk read
failure", I would be extremely displeased.

Note that I didn't catch UnicodeDecodeError here. If the file you're
trying to read isn't a text file, the exception will terminate the
process. Perhaps you decide that this should be handled too; all you
have to do is add it to the existing except clause, or add a second
one to handle this differently (maybe just "except UnicodeDecodeError:
print('is binary')"). That's the beauty of exception handling; you
handle as many or as few types as make sense for you to handle.

> And, forgetting file input for a minute, what about function return values
> in general; should they still be allowed to return some status or error
> codes, or does it all have to be exceptions now?
>
> I mean, is a function allowed to still return True or False, or just False?
> (Or perhaps just nothing if the exception mechanism can signal either.)

Depends on what those return values mean! If they mean exceptional
conditions, perhaps they should be changed; if they mean return
values, of course they shouldn't.

ChrisA



More information about the Python-list mailing list