argparse中有条件的可选标志

时间:2014-01-02 20:16:50

标签: python argparse

我正在编写一个程序,它将url列表作为参数。或者,我希望还能够包含一个包含其他网址列表的文件。因此,程序帮助看起来像下面的组合:

usage: [-h] url [url ...]

usage: [-h] --input-file file [ url [url ...]]

我目前将其编程为:

usage: [-h] [--input-file file] [url [url ...]]

其中--input-file的使用和指定至少一个网址都是可选的。然后我会检查自己是否指定了input-file或网址列表。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-i','--input-file', help="File of urls to be read")
parser.add_argument('urls',nargs='*')
args = parser.parse_args()
if not args.input_list and not args.urls:
    parser.error('must have either an input-file or a url') 

在argparse中是否存在一种方法,如果没有给出输入文件,我可以强制用户指定一个url,但如果是,则将其设为可选项?

2 个答案:

答案 0 :(得分:3)

如果您指定fromfile-prefix-chars(例如@),则用户可以指定一个文件来读取这些网址。读取此文件的行并将其添加到sys.argv,就好像它们已在命令行中键入一样。

http://docs.python.org/dev/library/argparse.html#fromfile-prefix-chars

parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument('urls',nargs='+')  # require 1 or more url
args = parser.parse_args()

这些都是有效的(urls.txt每行有一个url字符串)

parser.parse_args('four.txt'.split())
parser.parse_args('@urls.txt four.txt'.split())
parser.parse_args('@urls.txt'.split())

虽然没有文件或网址发出错误

parser.parse_args(''.split())

默认help没有说明允许@url.txt文件名,但您可以将其添加到自定义说明字符串中。

PS - 你的argparse后测试比你在argparse中指定的任何东西都简单。涉及-i参数和位置的必需互斥组可能有效,但它不会比您的测试做得多。我写了'可能',因为我必须加倍一个'*'位置是否适用于这样一个组。但这是我见过的第一个fromfile_prefix_chars选项真正有用的案例之一。

答案 1 :(得分:0)

ArgumentParser.add_mutually_exclusive_group()应该可以帮助您实现目标。请查看https://docs.python.org/2/library/argparse.html#mutual-exclusion上的示例或以下代码:

~#: cat urls.py
import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-infile', dest='file', help='File of URLs to be read')
group.add_argument('-urls', dest='urls', nargs='+', help='One or more URLs')

args = parser.parse_args()

~#: python urls.py
usage: urls.py [-h] (-infile FILE | -urls URLS [URLS ...])
urls.py: error: one of the arguments -infile -urls is required