argparse中的详细级别与多个-v选项
我想在命令行中通过添加更多的-v选项来设置不同的详细程度。例如:
$ myprogram.py
$ myprogram.py -v
$ myprogram.py -vv
$ myprogram.py -v -v -v
这样就可以分别设置为verbose=0、verbose=1、verbose=2和verbose=3。请问我该如何使用argparse来实现这个功能呢?
另外,如果能像下面这样指定就更好了:
$ myprogram -v 2
8 个回答
15
你可以用 append_const
来处理你问题的第一部分。否则,你可能需要写一个自定义的操作,就像 unutbu 在他的回答中提到的那样。
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)
185
argparse支持一种叫做 action='count'
的功能:
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)
唯一需要注意的小细节是,如果你希望没有 -v
参数时的输出等级是0,而不是 None
,你需要明确设置 default=0
。
28
你可以使用 nargs='?'
这个设置(它可以接受在 -v
标志后面跟0个或1个参数)和一个自定义的动作(用来处理这0个或1个参数):
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))
在命令行中运行 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)
取消注释打印语句,可以更清楚地看到 VAction
在做什么。