【发布时间】:2021-12-17 18:56:14
【问题描述】:
我想使用 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')
使用下面的这个命令,我们可以在这里看到它接受解析器member的参数addresses而不是参数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')
基本上,我希望有嵌套命令,但不一定有参数,反之亦然。
【问题讨论】:
-
明确指出哪些测试用例是意外的以及原因。代码太复杂,不明显。
-
感谢@hpaulj 重播。我在
----- EDIT -----之后添加了有关我的问题(问题)的更多详细信息。