python - 基于另一个参数向 argparse 添加参数的 Pythonic 方式
问题描述
在主函数中,我有一个验证可选输入的解析器:
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--platform',required=True)
parser.add_argument('--foo')
parser.add_argument('--bar')
parser.add_argument('--baz')
parser.parse_args()
上面的代码片段是一个示例,仅在我提供--platform和--foo、--bar或--baz 时才有效。
这段代码被不同的组件使用,我们称它们为组件A、B和C。
组件A实际上只指定了--foo和--bar:
python script.py --platform A --foo first_example --bar first_example
组件B实际上只指定--bar和--baz:
python script.py --platform B --bar second_example --baz second_exmaple
组件C实际上只指定--baz:
python script.py --platform C --baz third_example
随着我引入更多提供不同参数的组件,我必须添加到解析器的参数数量增加。以上只是一个示例,我目前正在处理 20 个左右的参数(将来可能会更多)。
我一直在考虑有一个配置文件(.yaml),我在其中定义每个组件需要哪些参数:
# parameters.yaml
A:
- foo
- bar
B:
- bar
- baz
C:
- baz
我想简化主函数以查看--platform 参数,并根据作为参数传递的平台,读取配置并向解析器添加其他参数。
这是我尝试过的:
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--platform',required=True)
# Read from .yaml file
with open('parameters.yaml') as parameter_file:
parameters = yaml.safe_load(parameter_file)
for argument in parameters[sys.argv[sys.argv.index('--platform') + 1]]:
parser.add_argument(
'--' + argument
)
parser.parse_args()
调用函数:
python script.py --platform C --baz third_example
上面的代码有效,但我正在寻找其他 Pythonic 解决方案,因为我是 Python 的初学者。我真的不喜欢查看sys.argv来确定--platform已指定什么。这个问题有更好的解决方案吗?
解决方案
使用子解析器作为子命令:
import argparse
def run_command(parser, args):
if args.command == 'A':
print(args)
elif args.command == 'B':
print(args)
elif args.command == 'C':
print(args)
parser = argparse.ArgumentParser(
prog='PROG',
epilog="See '<command> --help' to read about a specific sub-command."
)
subparsers = parser.add_subparsers(dest='command', help='Sub-commands')
A_parser = subparsers.add_parser('A', help='Platform A')
A_parser.add_argument("--foo")
A_parser.add_argument('--bar')
A_parser.set_defaults(func=run_command)
B_parser = subparsers.add_parser('B', help='Platform B')
B_parser.add_argument('--bar')
B_parser.add_argument('--baz')
B_parser.set_defaults(func=run_command)
C_parser = subparsers.add_parser('C', help='Platform C')
C_parser.add_argument('--baz')
C_parser.set_defaults(func=run_command)
args = parser.parse_args()
if args.command is not None:
args.func(parser, args)
else:
parser.print_help()
这会产生:
~ python args.py -h
usage: PROG [-h] {A,B,C} ...
positional arguments:
{A,B,C} Sub-commands
A Platform A
B Platform B
C Platform C
optional arguments:
-h, --help show this help message and exit
See '<command> --help' to read about a specific sub-command.
和
~ python args.py B -h
usage: PROG B [-h] [--bar BAR] [--baz BAZ]
optional arguments:
-h, --help show this help message and exit
--bar BAR
--baz BAZ
推荐阅读
- css - 样式表不再起作用,确实起作用了
- windows - 如何在批量扩展重命名时删除文件
- algorithm - 点数组中两点之间的最小欧几里得距离
- spring-boot - JHipster i18n 似乎坏了
- swift - 无法将“TaskElement”类型的值转换为预期的参数类型“EnvironmentObject”
' - github - 使组织中的私有存储库对一组人可见
- google-cloud-cdn - 太快了 Google CDN 缓存驱逐或错误
- amazon-web-services - DynamoDB 枚举转换版本 2
- tensorflow - 如果我使用预训练的嵌入模型,为什么 seq2seq 模型会返回负损失
- php - 无法在 codigniter 中上传图像,出现错误的路径错误