带ArgParse和多个-V选项的verbose级别 我希望能够通过在命令行中添加更多-v选项来指定不同的详细级别。例如: $ myProgram.py $ myProgram.py -v $ myProgram.py -vv $ myprogram.py -v -v -v -v -v ...

问题描述 投票:0回答:5
将导致详细= 0,冗长= 1,冗长= 2,冗长= 3。我该如何使用argparse实现这一目标? comptionion,也能够像

一样指定它可能很棒

$ myprogram -v 2
    

argparse支持

action='count'
python argparse
5个回答
192
投票
import argparse parser = argparse.ArgumentParser() parser.add_argument('-v', '--verbose', action='count', default=0) for c in ['', '-v', '-v -v', '-vv', '-vv -v', '-v -v --verbose -vvvv']: print(parser.parse_args(c.split()))

输出:


Namespace(verbose=0) Namespace(verbose=1) Namespace(verbose=2) Namespace(verbose=2) Namespace(verbose=3) Namespace(verbose=7)

唯一非常小的小麻烦是您必须明确设置
default=0

您可以使用
-v

(在

None
旗后接受0或1个参数)和一个自定义操作(处理0或1个参数):
nargs='?'
从命令行划出

-v

28
投票
import sys import argparse class VAction(argparse.Action): def __init__(self, option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None): super(VAction, self).__init__(option_strings, dest, nargs, const, default, type, choices, required, help, metavar) self.values = 0 def __call__(self, parser, args, values, option_string=None): # print('values: {v!r}'.format(v=values)) if values is None: self.values += 1 else: try: self.values = int(values) except ValueError: self.values = values.count('v')+1 setattr(args, self.dest, self.values) # test from the command line parser = argparse.ArgumentParser() parser.add_argument('-v', nargs='?', action=VAction, dest='verbose') args = parser.parse_args() print('{} --> {}'.format(sys.argv[1:], args)) print('-'*80) for test in ['-v', '-v -v', '-v -v -v', '-vv', '-vvv', '-v 2']: parser = argparse.ArgumentParser() parser.add_argument('-v', nargs='?', action=VAction, dest='verbose') args=parser.parse_args([test]) print('{:10} --> {}'.format(test, args))

comment the Print语句,以了解更好的

script.py -v -v
正在做什么。

您可以用

['-v', '-v'] --> Namespace(verbose=2) -------------------------------------------------------------------------------- -v --> Namespace(verbose=1) -v -v --> Namespace(verbose=2) -v -v -v --> Namespace(verbose=3) -vv --> Namespace(verbose=2) -vvv --> Namespace(verbose=3) -v 2 --> Namespace(verbose=2)
处理问题的第一部分。否则,您可能会陷入撰写自定义动作,如Unutbu
.

的Fine

andswer中所建议的那样。

VAction

输出:

append_const

    


15
投票

import argparse ap = argparse.ArgumentParser() ap.add_argument('-v', action = 'append_const', const = 1) for c in ['', '-v', '-v -v', '-vv', '-vv -v']: opt = ap.parse_args(c.split()) opt.v = 0 if opt.v is None else sum(opt.v) print opt

示例:

Namespace(v=0)
Namespace(v=1)
Namespace(v=2)
Namespace(v=2)
Namespace(v=3)


扩展UNUTBU的答案,这是一个自定义动作,包括处理 - Quiet/-Q组合。这是在Python3中测试的。在python> = 2.7中使用它应该没什么大不了的。

#!/usr/bin/env python import argparse import logging import sys LOG_LEVELS = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] DEFAULT_LOG_LEVEL = "INFO" def main(argv): parser = argparse.ArgumentParser() parser.add_argument( "--verbose", "-v", dest="log_level", action="append_const", const=-1, ) parser.add_argument( "--quiet", "-q", dest="log_level", action="append_const", const=1, ) args = parser.parse_args(argv[1:]) log_level = LOG_LEVELS.index(DEFAULT_LOG_LEVEL) # For each "-q" and "-v" flag, adjust the logging verbosity accordingly # making sure to clamp off the value from 0 to 4, inclusive of both for adjustment in args.log_level or (): log_level = min(len(LOG_LEVELS) - 1, max(log_level + adjustment, 0)) log_level_name = LOG_LEVELS[log_level] print(log_level_name) logging.getLogger().setLevel(log_level_name) if __name__ == "__main__": main(sys.argv)
是一种便利类方法,可用于为

9
投票

class ActionVerbose(argparse.Action): def __call__(self, parser, args, values, option_string=None): #print(parser, args, values, option_string) # Obtain previously set value in case this option call is incr/decr only if args.verbose == None: base = 0 else: base = args.verbose # One incr/decr is determined in name of option in use (--quiet/-q/-v/--verbose) option_string = option_string.lstrip('-') if option_string[0] == 'q': incr = -1 elif option_string[0] == 'v': incr = 1 else: raise argparse.ArgumentError(self, 'Option string for verbosity must start with v(erbose) or q(uiet)') # Determine if option only or values provided if values==None: values = base + incr else: # Values might be an absolute integer verbosity level or more 'q'/'v' combinations try: values = int(values) except ValueError: values = values.lower() if not re.match('^[vq]+$', values): raise argparse.ArgumentError(self, "Option string for -v/-q must contain only further 'v'/'q' letters") values = base + incr + values.count('v') - values.count('q') setattr(args, self.dest, values) @classmethod def add_to_parser(cls, parser, dest='verbose', default=0, help_detail='(0:errors, 1:info, 2:debug)'): parser.add_argument('--verbose', nargs='?', action=ActionVerbose, dest=dest, metavar='level', default=default, help='Increase or set level of verbosity {}'.format(help_detail)) parser.add_argument('-v', nargs='?', action=ActionVerbose, dest=dest, metavar='level', help='Increase or set level of verbosity') parser.add_argument('--quiet', nargs='?', action=ActionVerbose, dest=dest, metavar='level', help='Decrease or set level of verbosity') parser.add_argument('-q', nargs='?', action=ActionVerbose, dest=dest, metavar='level', help='Decrease or set level of verbosity') --verbose

-v

-q

--quiet

4
投票
,设置所有四个选项处理程序。这样使用:

./script -vvvvvv -v 4 -v 0 -v -vvv --verbose --quiet 2 -v qqvvqvv
使用具有以下论点可以做的脚本时:

args.verbose
以此命令行为
4
任何给定数字的人是一个很难,绝对的集合
-v/-q/--verbose/--quiet

(= verbosity级别)。
没有数字的任何人是该级别的增量。
没有一个数字的任何一个水平的降低。

任何人可能会立即随访更多的字母,由此产生的级别为

args.verbose

默认值为0



如果您想要不同的行为,则自定义操作应该很容易修改。例如,有些人更喜欢任何一个将级别重置为0,甚至将水平重置为-1。为此,从
-v/--verbose

    -q/--quiet
  • 的add_argument中删除了
    -v/-q
    ,也可以进行硬码以设置
    v/q
    .
  • 。 如果使用错误,则可以很好地打印proper解析器错误:
  • the old level + sum(count('v')) - sum(count('q'))
  • --quiet
  • 支持
  • nargs
    动作,该操作使您可以指定多个参数。检查
    Http://docs.python.org/library/argparse.html
    ,搜索“
    -q
    ”。
        
  • 您首先提出的方法更有可能混淆。不同级别的冗长级别的不同选项名称,或一个详细标志,然后选择一个冗长级别的数字指标,不太可能使用户混淆,并且可以更加灵活地分配冗长级别。
  • 我想出了另一种选择;虽然它不匹配OP的请求,但它满足了我的要求,我认为值得分享。
使用互斥的组来计算短选项的数量或存储长选项的整数值。

--quiet

value = 0
您可以看到,它允许您“堆叠”单个字符选项,并允许您使用长选项名称明确设置该值。  缺点是您不能将长选项用作开关(最后一个示例会生成异常。)
    
simpler方法:
if option_string[0] == 'q'
	

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.