argparse:nargs的默认值=' *'?

时间:2014-02-11 13:26:53

标签: python argparse

我试图使用这句话:

parser = argparse.ArgumentParser()
parser.add_argument('-m', '--music', nargs='*', default=False, const=True)
args = parser.parse_args()
print(args.music)

但得到了这个错误:

`builtins.ValueError: nargs must be '?' to supply const`

我想做的是:

  • 如果-m在args列表中但没有任何值,args.music会给我True
  • 如果-m在args列表中并且具有'N'值,则args.music将为我提供所有值的列表
  • 如果-m不在args列表中,则args,音乐将返回False

第二个和最后一个工作但是,当我尝试使用const时我得到了一个错误

3 个答案:

答案 0 :(得分:3)

您可以使用custom action

import argparse
class EmptyIsTrue(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        if len(values) == 0:
            values = True
        setattr(namespace, self.dest, values)

parser = argparse.ArgumentParser()
parser.add_argument('-m', '--music', nargs='*', default=False, action=EmptyIsTrue)
print(parser.parse_args([]))
# Namespace(music=False)

print(parser.parse_args(['-m']))
# Namespace(music=True)

print(parser.parse_args('-m 1 2'.split()))
# Namespace(music=['1', '2'])

如果只有一个参数可以处理这种方式,那么

arg.music = True if len(arg.music) == 0 else arg.music

更简单。如果你有很多这样的参数,那么定义一个自定义动作可以减少重复,并帮助确保所有这些参数的处理方式相同。

答案 1 :(得分:0)

argparse部分解决您的问题之后的以下黑客攻击:

import argparse

# Same as your code above
parser = argparse.ArgumentParser()
parser.add_argument('-m', '--music', nargs='*', default=False)
args = parser.parse_args()

# Modifies args.music: [] -> True
args.music = True if args.music==[] else args.music

print(args.music)

在命令行中测试,它给出:

$ python /tmp/blah.py -m
True

 $ python /tmp/blah.py -m 1 -m 2
['2']

$ python /tmp/blah.py -m 1 2 3
['1', '2', '3']

$ python /tmp/blah.py
False

答案 2 :(得分:0)

怎么样:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-m', '--music', nargs='*', default=False)
args = parser.parse_args()

if vars(args).get('music', False) is not False:
    if not args.music:
        args.music = True
print args.music

输出:

tmp:/>python arg.py
False
tmp:/>python arg.py -m
True
tmp:/>python arg.py -m 1 2 3
['1', '2', '3'] 
tmp:/>