argparse在处理接收全局选项的子命令时失败:
import argparse
p = argparse.ArgumentParser()
p.add_argument('--arg', action='store_true')
s = p.add_subparsers()
s.add_parser('test')
将p.parse_args('--arg test'.split())
工作,
但在p.parse_args('test --arg'.split())
上失败了。
任何人都知道python参数解析器能够正确处理子命令的全局选项吗?
答案 0 :(得分:6)
>>> from docopt import docopt
>>> usage = """
... usage: prog.py command [--test]
... prog.py another [--test]
...
... --test Perform the test."""
>>> docopt(usage, argv='command --test')
{'--test': True,
'another': False,
'command': True}
>>> docopt(usage, argv='--test command')
{'--test': True,
'another': False,
'command': True}
答案 1 :(得分:3)
Python世界中有大量的参数解析库。这里有一些我见过的,所有这些都应该能够解决你想要解决的问题(基于我最后一次玩它时对它们的模糊回忆):
答案 2 :(得分:3)
您可以轻松地将此参数添加到两个解析器(主解析器和子命令解析器)中:
import argparse
main = argparse.ArgumentParser()
subparser = main.add_subparsers().add_parser('test')
for p in [main,subparser]:
p.add_argument('--arg', action='store_true')
print main.parse_args('--arg test'.split()).arg
print main.parse_args('test --arg'.split()).arg
修改:正如@hpaulj在评论中指出的那样,您还可以将parents
参数传递给ArgumentParser
构造函数或add_parser
方法。您可以列出此值解析器,它们是新解析器的基础。
import argparse
base = argparse.ArgumentParser(add_help=False)
base.add_argument('--arg', action='store_true')
main = argparse.ArgumentParser(parents=[base])
subparser = main.add_subparsers().add_parser('test', parents=[base])
print main.parse_args('--arg test'.split()).arg
print main.parse_args('test --arg'.split()).arg
更多示例/文档:
Python argparse - Add argument to multiple subparsers(我不确定这个问题是否与此问题不重叠)
答案 3 :(得分:2)
这是一个肮脏的解决方法 -
import argparse
p = argparse.ArgumentParser()
p.add_argument('--arg', action='store_true')
s = p.add_subparsers()
s.add_parser('test')
def my_parse_args(ss):
#parse the info the subparser knows about; don't issue an error on unknown stuff
namespace,leftover=p.parse_known_args(ss)
#reparse the unknown as global options and add it to the namespace.
if(leftover):
s.add_parser('null',add_help=False)
p.parse_args(leftover+['null'],namespace=namespace)
return namespace
#print my_parse_args('-h'.split()) #This works too, but causes the script to stop.
print my_parse_args('--arg test'.split())
print my_parse_args('test --arg'.split())
这很有效 - 你可以很容易地修改它以使用sys.argv
(只需删除拆分字符串“ss
”)。您甚至可以继承argparse.ArgumentParser
并将parse_args
方法替换为my_parse_args
然后您永远不会知道其中的区别 - 虽然替换单个方法的子类化对我来说似乎有点过分了。
答案 4 :(得分:1)
解析器具有特定的语法:command <global options> subcommand <subcommand ptions>
,您尝试使用选项提供子命令,但您没有定义一个。