如何停止argparse.FileType创建指定为默认的文件

时间:2013-09-27 16:11:14

标签: python argparse

我喜欢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

但如果觉得这样比较容易,我会错过什么吗?

1 个答案:

答案 0 :(得分:3)

argparsehttp://bugs.python.org/issue12776(2012年8月)进行了相对较新的更改,延迟了对默认值的评估。最初,字符串默认值将在解析开始时通过type(通过_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...)包裹在partial中。这样,在实际用于with 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')