2011-11-23 83 views
12

比方说,我有一个脚本,在文件上做一些工作。它会在命令行中使用该文件的名称,但如果未提供该文件,则默认为已知文件名(例如content.txt)。与python的​​,我使用以下内容:用argparse指定默认文件名,但不打开它们--help?

parser = argparse.ArgumentParser(description='my illustrative example') 
parser.add_argument('--content', metavar='file', 
        default='content.txt', type=argparse.FileType('r'), 
        help='file to process (defaults to content.txt)') 
args = parser.parse_args() 
# do some work on args.content, which is a file-like object 

这很好。唯一的问题是,如果我运行python myscript --help,如果文件不存在(我认为有意义),则获得ArgumentError,并且不显示帮助文本。我宁愿它不尝试打开文件,如果用户只想要--help。有没有办法做到这一点?我知道我可以将参数设置为一个字符串,并在以后自己打开文件(我一直这样做),但是​​可以很方便地处理它。

+0

嗯,它看起来像你必须在这里做一个决定。您可以使默认文件可用(由于它是“默认”),或者只是自己打开文件,就像您建议的那样。或者,您可以使用stdin作为默认值,但是您将无法指定默认文件名,如果您不想填充该文件,这可能不是一个错误的选项。 –

回答

9

望着argparse代码,我看到:

  • ArgumentParser.parse_args电话parse_known_args,并确保没有被解析任何未决的争论。
  • ArgumentParser.parse_known_args套的默认值,并调用ArgumentParser._parse_known_args

因此,解决方法是使用直接ArgumentParser._parse_known_args检测-h和,之后,用ArgumentParser.parse_args如常。

import sys, argparse 
parser = argparse.ArgumentParser(description='my illustrative example', argument_default=argparse.SUPPRESS) 
parser.add_argument('--content', metavar='file', 
        default='content.txt', type=argparse.FileType('r'), 
        help='file to process (defaults to content.txt)') 
parser._parse_known_args(sys.argv[1:], argparse.Namespace()) 
args = parser.parse_args() 

注意ArgumentParser._parse_known_args需要几个参数:在命令行和命名空间中的参数。

当然,我不会推荐这种方法,因为它利用了内部的​​实现,这在未来可能会改变。但是,我不觉得它太杂乱,所以如果您认为维护风险能够得到回报,您仍然可能会使用它。

+0

看起来这并不是一个很好的解决方案,但是这将用于一次性脚本。谢谢! –

1

也许你可以在add_argument调用,检查文件是否存在,如果它和None(或别的东西),否则返回一个文件句柄定义自己typeaction

尽管如此,这还是需要你自己写一些代码,但是如果不能总是使用默认值,那么你可能不得不迟早做一些检查。像曼尼D认为你可能想重新考虑你的默认值。

12

你可以继承argparse.FileType

import argparse 
import warnings 

class ForgivingFileType(argparse.FileType): 
    def __call__(self, string): 
     try: 
      super(ForgivingFileType,self).__call__(string) 
     except IOError as err: 
      warnings.warn(err) 

parser = argparse.ArgumentParser(description='my illustrative example') 
parser.add_argument('--content', metavar='file', 
        default='content.txt', type=ForgivingFileType('r'), 
        help='file to process (defaults to content.txt)') 
args = parser.parse_args() 

这工作,而无需触摸像ArgumentParser._parse_known_args私有方法。

2

使用标准输入默认:

parser.add_argument('file', default='-', nargs='?', type=argparse.FileType('r')) 
相关问题