我正在编写一个python命令行客户端程序来与api连接。用户使用客户端程序运行以下命令,客户端程序对api
进行以下示例调用python run.py --car - >调用方法get_all(vehicle_type)请求 - > / car / all - <返回所有汽车列表
python run.py --van - > / van / all - >返回所有货车的清单
/ car / id / 123 - > - >调用方法get_by_id(vehicle_type,id)请求 - >返回ID为123的汽车列表
与其他所有人相似。
/ car / color / red红色车的返回列表
/ car / model_no / 31x使用model_no 31x返回汽车
/ van / id / 312返回id为321的货车列表
我正在为此目的使用arg解析并且无法正确地执行此操作。现在,我在做。
parser = argparse.ArgumentParser()
grp1 = parser.add_mutually_exclusive_group(required=True)
grp2 = parser.add_mutually_exclusive_group()
grp1.add_argument('--car', action='store_const', const='car')
grp1.add_argument('--van', action='store_const', const='van')
grp2.add_argument('--id', help='get by id')
grp2.add_argument('--model_no', help='get by model number')
grp2.add_argument('--color', help='get by color')
arg_dict = {k:v for k, v in vars(args).items() if v}
当我为命令运行此代码时。
python run.py --car --id 123
我得到了
{'车' :' car' ,' id' :' 123'}
我循环遍历此dict并使用getattr通过键名称调用函数' get_by_ {name}' .format(name = key)。 但是,我的代码看起来并不好看,因为我必须检查长度是否为1,然后调用get all function并检查车辆类型。有没有更好的方法来正确使用argparse来使代码更紧凑。
答案 0 :(得分:2)
一个相对直接的做你想要的方式(我认为)是:
arg_dict = {k:v for k, v in vars(args).items() if v}
您可以使用if args.id:
...
将if hasattr(args,'id'):
...
与[{1}}保持一致(就像您对if get(vars,'id',None):
...
所做的那样。但是更容易测试
args
大于
locals()
或
argparse
如果您真的想从registries
值生成函数名,可以进行字典查找(parser.register
或自定义词典)。内部fn = locals().get('get_by_%s'%'id')
fn(args.vehicle_type, args.id)
通过argparse
使用parser.set_defaults
字典。
args
const
文档显示如何使用getby_group.add_argument('--id',dest='fn',action='store_const', const=get_by_id)
将args.fn(...)
属性定义为函数。但是这种特殊用途仅适用于subparsers。
您可以使用get_by_id
设置功能,例如
store_const
然后
fn
将运行value
函数。
<删除了使用此class GetAction(argparse._StoreAction):
# barest customization
def __init__(self, *args, **kwargs):
fn=kwargs.pop('fn')
super(GetAction, self).__init__(*args, **kwargs)
self.fn = fn
def __call__(self, parser, namespace, values, option_string=None):
super(GetAction, self).__call__(parser, namespace, values, option_string=None)
setattr(namespace, 'fn', self.fn)
parser.set_defaults(fn=get_all) # default action
getby_group.add_argument('--id', dest='value', action=GetAction, fn=get_by_id)
getby_group.add_argument('--color',dest='value', action=GetAction, fn=get_by_color)
getby_group.add_argument('--model',dest='value', action=GetAction, fn=get_by_model)
args = parser.parse_args()
args.fn(args.vehicle_type, args.value)
的版本。接受价值时遇到了问题;设置编辑历史记录以获取详细信息>
===================
以下是定义if-else
属性和spriteCircle.body.damping = 0.9;
0
但是 - 请注意,类定义需要比1
树更多的代码行。并且花了我更长的时间来写作。
答案 1 :(得分:1)
我发现在使用mutual_exclusive_groups时我经常使用dest
option,因此你有一个带有动态值的变量:
DimCities[ExitCity]
然后对于第二组,您可以在指定选项时使用import argparse
parser = argparse.ArgumentParser()
grp1 = parser.add_mutually_exclusive_group(required=True)
grp2 = parser.add_mutually_exclusive_group()
group_1_options = {"action":"store_const",'dest':"vehicle"}
grp1.add_argument('--car', const="car", **group_1_options)
grp1.add_argument('--van', const='van', **group_1_options)
应用更改,以便保存对指定选项文本的引用:
type
然后可以检索请求,如:
parser.set_defaults(request=("get_all",None))
request_args = {"id":'get by id',
"model_no":"get by model number",
"color":"get by color"}
grp2 = parser.add_mutually_exclusive_group()
for arg_name, help_text in request_args.items():
grp2.add_argument("--"+arg_name, help=help_text, dest="request",
type=(lambda x, arg_text=arg_name:(arg_text,x)))
然后您可以保证只需处理def test(argline):
namespace = parser.parse_args(argline.split())
kind,value = namespace.request
print(namespace.vehicle, kind, value)
和vehicle
选项:
request