在 Python 的 argparse 中多次使用相同的选项
Using the same option multiple times in Python's argparse
我正在尝试编写一个接受多个输入源并对每个输入源执行某些操作的脚本。像这样
./my_script.py \
-i input1_url input1_name input1_other_var \
-i input2_url input2_name input2_other_var \
-i input3_url input3_name
# notice inputX_other_var is optional
但我不太明白如何使用 argparse
来做到这一点。似乎设置了每个选项标志只能使用一次。我知道如何将多个参数与单个选项(nargs='*'
或 nargs='+'
)相关联,但这仍然不允许我多次使用 -i
标志。我该怎么做才能做到这一点?
明确一点,我最后想要的是一个字符串列表列表。所以
[["input1_url", "input1_name", "input1_other"],
["input2_url", "input2_name", "input2_other"],
["input3_url", "input3_name"]]
-i
应配置为接受 3 个参数并使用 append
操作。
>>> p = argparse.ArgumentParser()
>>> p.add_argument("-i", nargs=3, action='append')
_AppendAction(...)
>>> p.parse_args("-i a b c -i d e f -i g h i".split())
Namespace(i=[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']])
要处理可选值,您可以尝试使用简单的自定义类型。在这种情况下,-i
的参数是单个逗号分隔的字符串,分割数限制为 2。您需要 post 处理这些值以确保至少有两个值指定。
>>> p.add_argument("-i", type=lambda x: x.split(",", 2), action='append')
>>> print p.parse_args("-i a,b,c -i d,e -i g,h,i,j".split())
Namespace(i=[['a', 'b', 'c'], ['d', 'e'], ['g', 'h', 'i,j']])
要获得更多控制,请定义自定义操作。这扩展了内置 _AppendAction
(由 action='append'
使用),但只是对给定 -i
.
的参数数量进行一些范围检查
class TwoOrThree(argparse._AppendAction):
def __call__(self, parser, namespace, values, option_string=None):
if not (2 <= len(values) <= 3):
raise argparse.ArgumentError(self, "%s takes 2 or 3 values, %d given" % (option_string, len(values)))
super(TwoOrThree, self).__call__(parser, namespace, values, option_string)
p.add_argument("-i", nargs='+', action=TwoOrThree)
这是一个解析器,它处理重复的 2 个可选参数 - 名称在 metavar
:
中定义
parser=argparse.ArgumentParser()
parser.add_argument('-i','--input',action='append',nargs=2,
metavar=('url','name'),help='help:')
In [295]: parser.print_help()
usage: ipython2.7 [-h] [-i url name]
optional arguments:
-h, --help show this help message and exit
-i url name, --input url name
help:
In [296]: parser.parse_args('-i one two -i three four'.split())
Out[296]: Namespace(input=[['one', 'two'], ['three', 'four']])
这不能处理 2 or 3 argument
情况(虽然我前段时间写了一个补丁 Python bug/issue 可以处理这样的范围)。
使用 nargs=3
和 metavar=('url','name','other')
的单独参数定义如何?
元组 metavar
也可以与 nargs='+'
和 nargs='*'
一起使用; 2 个字符串用作 [-u A [B ...]]
或 [-u [A [B ...]]]
.
这很简单;只需添加 action='append'
和 nargs='*'
(或 '+'
)。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', action='append', nargs='+')
args = parser.parse_args()
然后当你 运行 它时,你会得到
In [32]: run test.py -i input1_url input1_name input1_other_var -i input2_url i
...: nput2_name input2_other_var -i input3_url input3_name
In [33]: args.i
Out[33]:
[['input1_url', 'input1_name', 'input1_other_var'],
['input2_url', 'input2_name', 'input2_other_var'],
['input3_url', 'input3_name']]
我正在尝试编写一个接受多个输入源并对每个输入源执行某些操作的脚本。像这样
./my_script.py \
-i input1_url input1_name input1_other_var \
-i input2_url input2_name input2_other_var \
-i input3_url input3_name
# notice inputX_other_var is optional
但我不太明白如何使用 argparse
来做到这一点。似乎设置了每个选项标志只能使用一次。我知道如何将多个参数与单个选项(nargs='*'
或 nargs='+'
)相关联,但这仍然不允许我多次使用 -i
标志。我该怎么做才能做到这一点?
明确一点,我最后想要的是一个字符串列表列表。所以
[["input1_url", "input1_name", "input1_other"],
["input2_url", "input2_name", "input2_other"],
["input3_url", "input3_name"]]
-i
应配置为接受 3 个参数并使用 append
操作。
>>> p = argparse.ArgumentParser()
>>> p.add_argument("-i", nargs=3, action='append')
_AppendAction(...)
>>> p.parse_args("-i a b c -i d e f -i g h i".split())
Namespace(i=[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']])
要处理可选值,您可以尝试使用简单的自定义类型。在这种情况下,-i
的参数是单个逗号分隔的字符串,分割数限制为 2。您需要 post 处理这些值以确保至少有两个值指定。
>>> p.add_argument("-i", type=lambda x: x.split(",", 2), action='append')
>>> print p.parse_args("-i a,b,c -i d,e -i g,h,i,j".split())
Namespace(i=[['a', 'b', 'c'], ['d', 'e'], ['g', 'h', 'i,j']])
要获得更多控制,请定义自定义操作。这扩展了内置 _AppendAction
(由 action='append'
使用),但只是对给定 -i
.
class TwoOrThree(argparse._AppendAction):
def __call__(self, parser, namespace, values, option_string=None):
if not (2 <= len(values) <= 3):
raise argparse.ArgumentError(self, "%s takes 2 or 3 values, %d given" % (option_string, len(values)))
super(TwoOrThree, self).__call__(parser, namespace, values, option_string)
p.add_argument("-i", nargs='+', action=TwoOrThree)
这是一个解析器,它处理重复的 2 个可选参数 - 名称在 metavar
:
parser=argparse.ArgumentParser()
parser.add_argument('-i','--input',action='append',nargs=2,
metavar=('url','name'),help='help:')
In [295]: parser.print_help()
usage: ipython2.7 [-h] [-i url name]
optional arguments:
-h, --help show this help message and exit
-i url name, --input url name
help:
In [296]: parser.parse_args('-i one two -i three four'.split())
Out[296]: Namespace(input=[['one', 'two'], ['three', 'four']])
这不能处理 2 or 3 argument
情况(虽然我前段时间写了一个补丁 Python bug/issue 可以处理这样的范围)。
使用 nargs=3
和 metavar=('url','name','other')
的单独参数定义如何?
元组 metavar
也可以与 nargs='+'
和 nargs='*'
一起使用; 2 个字符串用作 [-u A [B ...]]
或 [-u [A [B ...]]]
.
这很简单;只需添加 action='append'
和 nargs='*'
(或 '+'
)。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', action='append', nargs='+')
args = parser.parse_args()
然后当你 运行 它时,你会得到
In [32]: run test.py -i input1_url input1_name input1_other_var -i input2_url i
...: nput2_name input2_other_var -i input3_url input3_name
In [33]: args.i
Out[33]:
[['input1_url', 'input1_name', 'input1_other_var'],
['input2_url', 'input2_name', 'input2_other_var'],
['input3_url', 'input3_name']]