The argparse docs don't say who's responsible for closing FileType objects
Peter Otten
__peter__ at web.de
Tue May 30 02:03:48 EDT 2017
Bob Kline wrote:
> The subject line pretty much says it all. Should the programmer close the
> file? If the programmer does that, and the user has asked that the file
> object be hooked up to standard in (or standard out) what will happen? If
> the programmer doesn't close it, does it get closed cleanly in the face of
> an exception?
>
> Thanks!
There's an example in the module docstring:
"""
The following is a simple usage example that sums integers from the
command-line and writes the result to a file::
parser = argparse.ArgumentParser(
description='sum the integers at the command line')
parser.add_argument(
'integers', metavar='int', nargs='+', type=int,
help='an integer to be summed')
parser.add_argument(
'--log', default=sys.stdout, type=argparse.FileType('w'),
help='the file where the sum should be written')
args = parser.parse_args()
args.log.write('%s' % sum(args.integers))
args.log.close()
"""
To handle exceptions you can rewrite
args.log.write('%s' % sum(args.integers))
args.log.close()
as
with args.log as outstream:
outstream.write('%s' % sum(args.integers))
The reason I still don't use FileType is that I usually don't want to
(1) open the file immediately in parse_args()
(2) close sys.stdXXX
My workaround are various wrappers along the line of myopen() below...
$ cat argparse_myopen.py
import argparse
import sys
from contextlib import contextmanager
parser = argparse.ArgumentParser(
description='sum the integers at the command line')
parser.add_argument(
'integers', metavar='int', nargs='+', type=int,
help='an integer to be summed')
parser.add_argument(
'--log', default=sys.stdout,
help='the file where the sum should be written')
args = parser.parse_args()
@contextmanager
def myopen(file, mode= "r"):
assert mode == "w"
if hasattr(file, "write"):
yield file
else:
with open(file, mode) as outstream:
yield outstream
with myopen(args.log, "w") as out:
print(sum(args.integers), file=out)
assert out.closed == (out is not sys.stdout)
print("Bye")
$ python3 argparse_myopen.py 1 2 --log tmp.txt
Bye
$ cat tmp.txt
3
$ python3 argparse_myopen.py 2 3
5
Bye
...that I'm going to consolidate into a single one. Someday.
More information about the Python-list
mailing list