如何用argparse高效实现Python函数的命令行调用?
自动适配函数参数的命令行解析实现需求
需要通过命令行以如下形式调用Python函数:
python my_parser.py myfunction1 arg1 arg2
以及
python my_parser.py myfunction2 arg1 arg2 arg3
现有实现分为两个文件:file1.py存放所有函数,file2.py手动编写参数解析规则——新增函数时必须手动添加对应解析配置,效率极低。目标是将解析逻辑整合到file1.py的if __name__ == "__main__":代码块中,实现解析器自动适配函数参数,无需手动添加子解析器与参数定义,同时移除file2.py。
现有代码示例
file1.py
def my_func1(arg1, arg2): return arg1*arg2 def my_func2(arg1, arg2, arg3): return arg1*arg2*arg3 def my_func3(arg1): return print(arg1)
file2.py(手动解析器)
import argparse import file1 FUNCTION_MAP = {'my_func1': file1.my_func1, 'my_func2': file1.my_func2, 'my_func3': file1.my_func3} # 创建顶级解析器 parser = argparse.ArgumentParser(prog='PROG') subparsers = parser.add_subparsers(help='子命令帮助', dest='subparser_name') # 为my_func1添加子解析器 parser_a = subparsers.add_parser('my_func1', help='func1帮助') parser_a.add_argument("-arg1", "--arg1", required=True) parser_a.add_argument("-arg2", "--arg2", required=True) # 为my_func2添加子解析器 parser_b = subparsers.add_parser('my_func2', help='func2帮助') parser_b.add_argument("-arg1", "--arg1", required=True) parser_b.add_argument("-arg2", "--arg2", required=True) parser_b.add_argument("-arg3", "--arg3", required=True) # 为my_func3添加子解析器 parser_c = subparsers.add_parser('my_func3', help='func3帮助') parser_c.add_argument("-arg1", "--arg1", required=True) # 解析参数 args = parser.parse_args() # 获取对应函数 func = FUNCTION_MAP[args.subparser_name] # 转换为参数字典 func_args = vars(args) # 移除子命令名称(不是函数参数) del func_args['subparser_name'] # 调用函数 func(**func_args)
实现方案
利用Python的inspect模块自动获取函数参数信息,动态生成子解析器与对应参数,完全无需手动配置。以下是整合后的file1.py完整代码:
import argparse import inspect def my_func1(arg1, arg2): return arg1*arg2 def my_func2(arg1, arg2, arg3): return arg1*arg2*arg3 def my_func3(arg1): return print(arg1) if __name__ == "__main__": # 定义要暴露的函数映射(也可自动扫描当前模块函数,过滤非目标函数) FUNCTION_MAP = { 'my_func1': my_func1, 'my_func2': my_func2, 'my_func3': my_func3 } # 创建顶级解析器 parser = argparse.ArgumentParser(prog='PROG') subparsers = parser.add_subparsers(help='子命令帮助', dest='subparser_name', required=True) # 遍历函数,动态生成子解析器和参数 for func_name, func in FUNCTION_MAP.items(): # 获取函数参数签名 sig = inspect.signature(func) params = sig.parameters # 创建当前函数的子解析器 sub_parser = subparsers.add_parser(func_name, help=f'调用{func_name}函数') # 为每个参数添加命令行选项 for param_name in params: # 默认所有参数必填,可根据函数默认参数调整required属性 sub_parser.add_argument( f"--{param_name}", f"-{param_name[0]}", # 生成短选项,如arg1对应-a required=True, help=f"{param_name} 参数" ) # 解析命令行参数 args = parser.parse_args() # 获取目标函数并提取有效参数 target_func = FUNCTION_MAP[args.subparser_name] func_args = {k: v for k, v in vars(args).items() if k != 'subparser_name'} # 调用函数并输出结果 result = target_func(**func_args) if result is not None: print(result)
关键优化点
- 自动参数扫描:通过
inspect.signature获取函数参数列表,无需手动维护参数配置 - 动态子解析器生成:遍历函数映射,为每个函数自动创建对应的子解析器
- 智能选项生成:自动为每个参数生成长选项(
--arg1)和短选项(-a),可按需调整 - 支持可选参数:若函数含默认参数,可通过判断
param.default != inspect.Parameter.empty,将required设为False
使用示例
调用my_func1:
python file1.py my_func1 --arg1 2 --arg2 3
输出:6
调用my_func3:
python file1.py my_func3 --arg1 "Hello World"
输出:Hello World
内容的提问来源于stack exchange,提问作者Ulises Rey
相关产品推荐
相关产品推荐

