假设我有一个脚本可以对文件进行一些操作。它在命令行中使用此文件的名称,但如果未提供,则默认为已知文件名(例如content.txt
)。使用python的argparse
,我使用以下内容:
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
,我宁愿不尝试打开文件。有没有办法做到这一点?我知道我可以将参数设置为一个字符串,并在以后自己打开文件(我一直这样做),但让argparse
处理它会很方便。
答案 0 :(得分: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
等私密方法即可使用。
答案 1 :(得分: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
需要几个参数:命令行和命名空间中的参数。
当然,我不推荐这种方法,因为它利用了内部argparse
实现,并且可能在将来发生变化。但是,我发现它并不太杂乱,所以如果您认为维护风险得到了回报,您仍然可能想要使用它。
答案 2 :(得分:2)
使用stdin作为默认值:
parser.add_argument('file', default='-', nargs='?', type=argparse.FileType('r'))
答案 3 :(得分:1)