最近在命令行中使用了argparse.FileType()来传入一个文件,用于保存脚本处理的结果。代码大概如下。
parser = ArgumentParser()
parser.add_argument(
"--output_file",
type=FileType(mode="w"),
default=sys.stdout,
help="The output file of the result",
)
args = parser.parse_args()
这样args.output_file就可以直接使用进行写入操作了,因为argparse.FileType()在调用时已经帮你把文件打开了。由此想到,它是否把打开的文件在最后关闭了呢?看了一下源码argparse.py
,发现它只是将文件打开了,并没有进行关闭操作。具体代码如下。
class FileType(object):
def __call__(self, string):
# the special argument "-" means sys.std{in,out}
if string == '-':
if 'r' in self._mode:
return _sys.stdin
elif 'w' in self._mode:
return _sys.stdout
else:
msg = _('argument "-" with mode %r') % self._mode
raise ValueError(msg)
# all other arguments are used as file names
try:
return open(string, self._mode, self._bufsize, self._encoding,
self._errors)
except OSError as e:
message = _("can't open '%s': %s")
raise ArgumentTypeError(message % (string, e))
这可是标准的库啊,居然管杀不管埋。网上搜了一下,这个居然是个很老的Bug。不知道为什么一直没有修复。
只好自己动手,丰衣足食了。相应的关闭代码如下:
with contextlib.closing(args.output_file) as f:
something(f)