python - Python 无法解析嵌套参数
问题描述
我想使用 argparse 来解析我的应用程序参数。我尝试了很多东西,但我没有找到正确的方法。
在这里我想做(python3 app.py
与所有这些命令有关):
列表
list member <member_id>
list member addresses <member_id>
list members
list domains
list organisations
创造
create member <first_name> <last_name>
create member address <address> <display_name>
更新
update member name <member_id> <full_name>
update member storage <member_id> <storage_size>
删除
delete member <member_id>
禁用
disable member addresses <member_id>
disable member address <member_id> <addresses_id>
使能够
enable member addresses <member_id>
enable member address <member_id> <addresses_id>
这是我试图解析的内容List
,但是当有多个参数和解析器时我无法区分:
def list_member_addresses(args):
print(f'Member id {args.member_id}')
def list_member(args):
print(f'Member id {args.member_id}')
def list_members():
print('list members')
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='action', required=True)
# list
list_parser = subparsers.add_parser('list')
list_subparsers = list_parser.add_subparsers(dest='type', required = True)
# list members
members_parser = list_subparsers.add_parser('members')
members_parser.set_defaults(func=list_members)
# list member <member_id>
member_parser = list_subparsers.add_parser('member')
member_parser.add_argument('member_id')
member_parser.set_defaults(func=list_member)
# list member addresse <member_id>
addresses_member_subparser = member_parser.add_subparsers(dest='type')
addresses_member_parser = addresses_member_subparser.add_parser('addresses')
addresses_member_parser.add_argument('member_id')
addresses_member_parser.set_defaults(func=list_member_addresses)
# update
update_parser = subparsers.add_parser('update')
# TODO use similar case as "list"
# delete
delete_parser = subparsers.add_parser('delete')
# TODO use similar case as "list"
# enable
enable_parser = subparsers.add_parser('enable')
# TODO use similar case as "list"
# disable
disable_parser = subparsers.add_parser('disable')
# TODO use similar case as "list"
args = parser.parse_args()
# Commented on purpose
# args.func(args)
print(args)
测试输出:
user@hostname:$ python3 app.py list member
usage: test.py list member [-h] member_id {addresses} ...
test.py list member: error: the following arguments are required: member_id
user@hostname:$ python3 app.py list member member_id
Namespace(action='list', addresses=None, func=<function list_member at 0x7fa91eff85e0>, member_id='member_id', type='member')
user@hostname:$ python3 app.py list member addresses
Namespace(action='list', addresses=None, func=<function list_member at 0x7f1342e495e0>, member_id='addresses', type='member')
user@hostname:$ python3 app.py list member addresses member_id
usage: test.py list member [-h] member_id {addresses} ...
test.py list member: error: argument addresses: invalid choice: 'member_id' (choose from 'addresses')
user@hostname:$ python3 app.py list members
Namespace(action='list', func=<function list_members at 0x7f09a14b1670>, type='members')
您可以看到,在某些情况下,member_id
键具有addresses
作为值,但情况并非如此。此外,对于list member address
,我们不能添加member_id
参数。
你有什么主意吗 ?
- - - 编辑 - - -
在这里澄清我的期望和我得到的:
工作案例
list member <member_id>
user@hostname:$ python3 app.py list member member_id
Namespace(action='list', addresses=None, func=<function list_member at 0x7fa91eff85e0>, member_id='member_id', type='member')
list members
user@hostname:$ python3 app.py list members
Namespace(action='list', func=<function list_members at 0x7f09a14b1670>, type='members')
不工作的情况
list member addresses <member_id>
user@hostname:$ python3 app.py list member addresses member_id
usage: test.py list member [-h] member_id {addresses} ...
test.py list member: error: argument addresses: invalid choice: 'member_id' (choose from 'addresses')
使用下面的这个命令,我们可以在这里看到它接受addresses
解析器member
的参数addresses
而不是解析器的参数。
user@hostname:$ python3 test.py list member addresses
Namespace(action='list', func=<function list_member at 0x7f697cc3d5e0>, member_id='addresses', type=None)
在这里它正在工作,但不像预期的那样,因为我不想提供member_id1
,而是addresses
相反。
user@hostname:$ python3 test.py list member member_id1 addresses member_id2
Namespace(action='list', func=<function list_member_addresses at 0x7f1378530d30>, member_id='member_id2', type='addresses')
所以这就是我对该命令的期望:
user@hostname:$ python3 test.py list member addresses member_id
Namespace(action='list', func=<function list_member_addresses at 0x7f1378530d30>, member_id='member_id', type='addresses')
基本上,我希望有嵌套命令,但不一定有参数,反之亦然。
解决方案
和
python3 app.py list member addresses member_id
parser
看到“列表”,并将解析传递给list_parser
. 将解析传递给member_parser
.
那得到['addresses', [member_id']
. 根据usage
错误消息中的,“addresses”被分配给“member_id”属性,留下“member_id”进行测试{addresses}
:
usage: test.py list member [-h] member_id {addresses} ...
从代码中,member_parser
获取一个 'member_id' 位置,然后是一个 'subparsers' 位置:
member_parser = list_subparsers.add_parser('member')
member_parser.add_argument('member_id')
member_parser.set_defaults(func=list_member)
# list member addresse <member_id>
addresses_member_subparser = member_parser.add_subparsers(dest='type')
addresses_member_parser = addresses_member_subparser.add_parser('addresses')
addresses_member_parser
也需要一个 'member_id' 参数,但member_parsers
必须首先满足。
这应该有效:
python3 app.py list member member_id1 addresses member_id2
推荐阅读
- opengl - Why can I use GL_QUADS with glDrawArrays?
- windows - Windows 8/10 API Detect suspended process
- javascript - javascript 从数组创建嵌套的 JSON 数组
- dart - 如何在 BottomNavigationBarItem 中绝对定位徽章
- html - 对齐框内的图像、文本和标题
- python - 从匿名生成器构造列表的 Pythonic 习语
- laravel - Laravel - 如何在应用服务提供商中获取用户 ID
- php - 用户删除商品时如何自动更新购物车?
- verilog - 如何修复 Xst:528 此信号连接到多个驱动程序
- asp.net-mvc - ASP.NET Web API 和 MongoDB Atlas - 从数据库中检索特定数据的方法