9

我喜欢这个argparse模块。argparse.FileType也很有帮助,除非您希望默认值不是sys.std*因为即使您提供了一个值也会创建默认输出文件。

例如:

parser.add_argument('--outfile', type=FileType('w'), default="out.txt")

即使您使用 --outfile 指定文件,也会创建 out.txt。

我能想到的最好的是:

class MagicFileType(object):

    def __init__(self, *args, **kwargs):

        # save args/kwargs and set filetype to None
        self.filetype = None
        self.args = args
        self.kwargs = kwargs

    def __getattr__(self, attr):
        """ Delegate everything to the filetype """

        # If we haven't created it, now is the time to do so
        if self.filetype is None:
            self.filetype = FileType(*self.args, **self.kwargs)
            self.filetype = self.filetype(self.filename)

        return getattr(self.filetype, attr)

    def __call__(self, filename):
        """ Just cache the filename """

        # This is called when the default is created
        # Just cache the filename for now.
        self.filename = filename
        return self

但是,如果感觉这应该更容易,我是否错过了什么?

4

1 回答 1

3

有一个相对较新的变化argparsehttp://bugs.python.org/issue12776(2012 年 8 月),延迟了默认值的评估。最初,字符串默认值将在解析开始时通过type(via _get_value),导致 FileType 文件的打开(和创建)(无论是否需要)。在这个补丁中,字符串被写入命名空间,但直到解析结束时才被评估,此时它可以确定是否提供了另一个值。基本上,这条线是从早期移动parse_known_args到结束的_parse_known_args

default = self._get_value(action, action.default)

http://bugs.python.org/issue13824我提出了一个提供FileContext类型的补丁。它的主要区别在于FileType它将. 这样,文件在上下文中实际使用之前不会打开(或创建)。open(file...)partialwith args.output() as f:

该补丁处理其他一些事情,例如测试是否可以创建文件(使用os.access)并包装stdin/out在虚拟上下文中,因此它不会尝试关闭它。

无需测试,您可以FileType这样修改:

class FileOpener(argparse.FileType):
    # delayed FileType;
    # sample use:
    # with args.input.open() as f: f.read()
    def __call__(self, string):
        # optionally test string
        self.filename = string
        return self
    def open(self):
        return super(FileOpener,self).__call__(self.filename)
    file =  property(open, None, None, 'open file property')
于 2013-09-27T21:07:46.693 回答