我正在尝试构建一个命令行解析器,它能够在参数之间共享传递的值,以避免多次键入它们。换句话说,我希望两个参数的名称空间相同:
import argparse
class PrintAction(argparse.Action):
def __init__(self, option_strings, dest, **kwargs):
super(PrintAction, self).__init__(option_strings, dest, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
for val in values:
print(val)
parser = argparse.ArgumentParser(description='A foo that foos and a bar that bars')
parser.add_argument('--foo', action=PrintAction)
parser.add_argument('bar', nargs='+')
args = parser.parse_args(['--foo', 'a', 'b', 'c']) # Case 1
args = parser.parse_args(['a', 'b', 'c']) # Case 2
然后,我想要一个解决方案,在['a', 'b', 'c']
bar
中同时存储--foo
,但在提供a
的情况下,然后b
,{{1}将打印{}}和c
。
目前,我得到的是foo
只打印a
和bar
仅在b
中存储c
和case 1
并且正确结果为case 2
。
答案 0 :(得分:1)
您需要使--foo
成为布尔标志。现在它是一个字符串参数,因为你没有说明。将action设置为store_true
以获取布尔标志效果。
最终解决方案如下:
def print_args(args):
if args.foo:
for val in args.bar:
print(val)
parser = argparse.ArgumentParser(description='A foo that foos and a bar that bars')
parser.add_argument('--foo', action='store_true')
parser.add_argument('bar', nargs='+')
args = parser.parse_args(['--foo', 'a', 'b', 'c']) # Case 1
args = parser.parse_args(['a', 'b', 'c']) # Case 2
然后在第一种情况下调用print_args(args)
将打印a
,b
和c
,而在第二种情况下,则不会。{/ p>
答案 1 :(得分:1)
您无法(轻松)欺骗argparse
重用argv
字符串。解析器将值分配给Actions。
默认nargs
是None
,这意味着,使用下一个字符串作为参数。
parser.add_argument('--foo')
会设置foo='a'
和bar=['b','c']
。
在您的操作中,values
将是['a']
,您将其打印出来。在optparse
中,每个选项都会获得剩余的argv
列表,它可以根据需要使用它。在argparse
中,它只获得values
要求的nargs
。
您可以在__init__
中指定nargs=0
,然后从sys.argv
打印。等价,正如@ 9000建议的那样,将其设为store_true
并在解析后打印。查看store_true
Action类的代码。
另一种选择是同时为foo
和bar
提供*
,并foo
打印并保存到bar
dest
。然后foo
将使用以下所有字符串。但是,如果bar
没有要保存的内容,则可能会将[]
写入命名空间。
无论如何,你能做的最好就是假装重复使用。
另一个想法是使用2个不同的解析器parse_known_args
。解析器不会弄乱sys.argv
,因此它可以多次读取和解析。