問題描述
argparse 是否提供內(nèi)置的工具來讓它解析組或解析器進入他們自己的命名空間?我覺得我一定是在某個地方遺漏了一個選項.
Does argparse provide built-in facilities for having it parse groups or parsers into their own namespaces? I feel like I must be missing an option somewhere.
編輯:這個例子可能不完全是我應(yīng)該做的來構(gòu)建解析器來實現(xiàn)我的目標(biāo),但它是我到目前為止的工作.我的具體目標(biāo)是能夠為子解析器提供解析為命名空間字段的選項組.我對父母的想法只是為了同樣的目的使用通用選項.
Edit: This example is probably not exactly what I should be doing to structure the parser to meet my goal, but it was what I worked out so far. My specific goal is to be able to give subparsers groups of options that are parsed into namespace fields. The idea I had with parent was simply to use common options for this same purpose.
例子:
import argparse
# Main parser
main_parser = argparse.ArgumentParser()
main_parser.add_argument("-common")
# filter parser
filter_parser = argparse.ArgumentParser(add_help=False)
filter_parser.add_argument("-filter1")
filter_parser.add_argument("-filter2")
# sub commands
subparsers = main_parser.add_subparsers(help='sub-command help')
parser_a = subparsers.add_parser('command_a', help="command_a help", parents=[filter_parser])
parser_a.add_argument("-foo")
parser_a.add_argument("-bar")
parser_b = subparsers.add_parser('command_b', help="command_b help", parents=[filter_parser])
parser_b.add_argument("-biz")
parser_b.add_argument("-baz")
# parse
namespace = main_parser.parse_args()
print namespace
這顯然是我得到的:
$ python test.py command_a -foo bar -filter1 val
Namespace(bar=None, common=None, filter1='val', filter2=None, foo='bar')
但這才是我真正追求的:
But this is what I am really after:
Namespace(bar=None, common=None, foo='bar',
filter=Namespace(filter1='val', filter2=None))
然后更多的選項組已經(jīng)解析到命名空間中:
And then even more groups of options already parsed into namespaces:
Namespace(common=None,
foo='bar', bar=None,
filter=Namespace(filter1='val', filter2=None),
anotherGroup=Namespace(bazers='val'),
anotherGroup2=Namespace(fooers='val'),
)
我發(fā)現(xiàn)了一個 相關(guān)問題這里,但它涉及一些自定義解析,似乎只涵蓋了一個非常具體的情況.
I've found a related question here but it involves some custom parsing and seems to only covers a really specific circumstance.
是否有一個選項可以告訴 argparse 將某些組解析為命名空間字段?
Is there an option somewhere to tell argparse to parse certain groups into namespaced fields?
推薦答案
如果重點只是將選定的參數(shù)放在自己的 namespace
中,并且子解析器(和父級)的使用是偶然的這個問題,這個自定義操作可能會解決問題.
If the focus is on just putting selected arguments in their own namespace
, and the use of subparsers (and parents) is incidental to the issue, this custom action might do the trick.
class GroupedAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
group,dest = self.dest.split('.',2)
groupspace = getattr(namespace, group, argparse.Namespace())
setattr(groupspace, dest, values)
setattr(namespace, group, groupspace)
有多種方法可以指定group
名稱.它可以在定義動作時作為參數(shù)傳遞.它可以作為參數(shù)添加.這里我選擇從dest
解析(這樣namespace.filter.filter1
可以得到filter.filter1
的值.
There are various ways of specifying the group
name. It could be passed as an argument when defining the Action. It could be added as parameter. Here I chose to parse it from the dest
(so namespace.filter.filter1
can get the value of filter.filter1
.
# Main parser
main_parser = argparse.ArgumentParser()
main_parser.add_argument("-common")
filter_parser = argparse.ArgumentParser(add_help=False)
filter_parser.add_argument("--filter1", action=GroupedAction, dest='filter.filter1', default=argparse.SUPPRESS)
filter_parser.add_argument("--filter2", action=GroupedAction, dest='filter.filter2', default=argparse.SUPPRESS)
subparsers = main_parser.add_subparsers(help='sub-command help')
parser_a = subparsers.add_parser('command_a', help="command_a help", parents=[filter_parser])
parser_a.add_argument("--foo")
parser_a.add_argument("--bar")
parser_a.add_argument("--bazers", action=GroupedAction, dest='anotherGroup.bazers', default=argparse.SUPPRESS)
...
namespace = main_parser.parse_args()
print namespace
我必須添加 default=argparse.SUPPRESS
以便 bazers=None
條目不會出現(xiàn)在主命名空間中.
I had to add default=argparse.SUPPRESS
so a bazers=None
entry does not appear in the main namespace.
結(jié)果:
>>> python PROG command_a --foo bar --filter1 val --bazers val
Namespace(anotherGroup=Namespace(bazers='val'),
bar=None, common=None,
filter=Namespace(filter1='val'),
foo='bar')
如果您需要嵌套命名空間中的默認條目,您可以事先定義命名空間:
If you need default entries in the nested namespaces, you could define the namespace before hand:
filter_namespace = argparse.Namespace(filter1=None, filter2=None)
namespace = argparse.Namespace(filter=filter_namespace)
namespace = main_parser.parse_args(namespace=namespace)
結(jié)果和以前一樣,除了:
result as before, except for:
filter=Namespace(filter1='val', filter2=None)
這篇關(guān)于帶有嵌套命名空間的 argparse 子命令的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!