Python 分析多个子parser,但使用全局参数
我已经阅读了很多关于如何定义、解析和运行多个子parser来运行类似的东西的问题和答案Python 分析多个子parser,但使用全局参数,python,argparse,Python,Argparse,我已经阅读了很多关于如何定义、解析和运行多个子parser来运行类似的东西的问题和答案 tool.py func_a -a 12 func_b -b 15 input.txt output.txt ^-- main parser args ^--------------- subparser b ^---------------------------- subparse
tool.py func_a -a 12 func_b -b 15 input.txt output.txt
^-- main parser args
^--------------- subparser b
^---------------------------- subparser a
他们通常建议如下:
def func_a(args):
pass
def func_b(args):
pass
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# Define subparsers
subp_a = subparsers.add_parser(func_a.__name__)
subp_a.set_defaults(func=func_a)
subp_a.add_argument('-a')
subp_b = subparsers.add_parser(func_b.__name__)
subp_b.set_defaults(func=func_b)
subp_b.add_argument('-b')
# Define global parameters
parser.add_argument('input', type=argparse.FileType('r'))
parser.add_argument('output', type=argparse.FileType('wb', 0))
# Parse and run through all arguments
rest = sys.argv[1:]
while rest:
args, rest = parser.parse_known_args(rest)
args.func(args)
但是这个实现有一个问题:参数input
和output
是为主解析器定义的,应该只使用一次。但是,parser.parse\u known\u args(rest)
的每次调用都需要设置值,并因此将其从rest
中删除
这意味着对parse_known_args
的第一次调用将检索值,随后的每个调用都会由于缺少参数而失败
是否有一种解决方案可以在不手动将值复制到
rest
列表的情况下克服此问题?是的,第一个parse_known_args
使用文件名和第一个子parser级别
您可以定义两个解析器,一个具有“全局”位置,另一个不具有。首先使用“with”解析器解析,挂起它的args
(用于文件名)。然后使用'without'解析器沿着子parser堆栈进行分析
下面是一个简单的例子:
parser = argparse.ArgumentParser()
parser.add_argument('foo')
subp = parser.add_subparsers(dest='cmd')
cmd1 = subp.add_parser('cmd1')
cmd1.add_argument('-a')
cmd2 = subp.add_parser('cmd2')
# parser.add_argument('bar') # confusing location
parser1 = argparse.ArgumentParser()
subp = parser1.add_subparsers(dest='cmd')
cmd1 = subp.add_parser('cmd1', parents=[cmd1], add_help=False)
cmd2 = subp.add_parser('cmd2')
# Parse and run through all arguments
args, rest = parser.parse_known_args()
print args, rest
while rest:
args, rest = parser1.parse_known_args(rest)
print args, rest
我把解析器
foo
放在subp
之前,因为它在那里产生的混乱更少。末尾的位置(条
)可能与其中一个子parser或其中一个嵌套子parser的参数混淆,尤其是在生成错误消息时
要了解parse_args
如何将参数字符串分配到各个位置,请尝试以下脚本:
parser = argparse.ArgumentParser()
parser.add_argument('foo')
parser.add_argument('cmd', nargs=argparse.PARSER, choices=['cmd1','cmd2'])
parser.add_argument('bar')
print parser.parse_args()
对于解析器
,subparsers参数看起来就像至少包含一个字符串的位置(有点像'+'
),第一个必须匹配选项
。它将接收所有“剩余”字符串,与其他位置的要求一致