open() and EOFError

Chris Angelico rosuav at gmail.com
Mon Jul 7 15:27:19 CEST 2014


On Mon, Jul 7, 2014 at 11:06 PM, Mark Lawrence <breamoreboy at yahoo.co.uk> wrote:
> On 07/07/2014 09:09, Chris Angelico wrote:
>>
>> It seems trivial in this example to break it into two try blocks:
>>
>> try:
>>      name = input("Enter file name, or Ctrl-D to exit")
>>      # On Windows, use Ctrl-Z [enter] instead.
>> except EOFError:
>>      sys.exit()
>> try:
>>      fp = open(name)
>> except IOError:
>>      handle_bad_file(name)
>> else:
>>      handle_good_file(fp)
>>
>
> All those extra lines to type, not on your life.  Surely it would be better
> written as a one liner?

Challenge accepted! I shall wield the power of PEP 463, even though it
never got accepted, and pretend that it's a standard feature!

name = (input("Enter file name, or Ctrl-D to exit") except EOFError: sys.exit())
(handle_good_file(open(name)) except IOError: handle_bad_file(name))

Readers with a degree in higher mathematics will note that this is not
one, but two lines. It can be turned into one line, however the
forking out of the name requires some cheating. But since the last
part is now an expression, we have the option of lambda shenanigans...

(lambda n:(handle_good_file(open(n))except
IOError:handle_bad_file(n)))(input("Enter file name, or Ctrl-D to
exit")except EOFError:sys.exit())

Et voila! A single line, albeit 142 characters long, and that with
superfluous (ha!) internal spaces removed. As a side-effect of
expressionization (if that's a word), the code now catches IOError
from inside handle_good_file() by going to handle_bad_file, which is
almost certainly a bad idea (most likely, handle_good_file is going to
read from that file). But it's much more important that this be a
one-liner!

Alternatively, the nesting could be inverted. As long as
handle_bad_file() returns something which is not a file pointer (eg
None), and handle_good_file is carefully written to quietly do nothing
if given that, the original semantics could be retained:

(lambda n:(handle_good_file(open(n)except
IOError:handle_bad_file(n))))(input("Enter file name, or Ctrl-D to
exit")except EOFError:sys.exit())

Take your pick. And enjoy! :)

ChrisA



More information about the Python-list mailing list