在主函数中,我有一个解析器,用于验证可选输入:
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 或< em>-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 参数,并基于已将哪个平台作为参数传递,读取配置并将其他参数添加到解析器。 / p>
这是我尝试过的:
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
上面的代码可以工作,但是由于我是Python的初学者,因此我正在寻找其他Pythonic解决方案。一世 不需要查看 sys.argv 来确定已指定了什么-platform 。有没有更好的解决方案来解决这个问题?
答案 0 :(得分:2)
使用子解析器作为子命令:
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
答案 1 :(得分:1)
使用断言。
如果要禁止某些参数,可以添加assert
。示例:
parser = argparse.ArgumentParser()
parser.add_argument('--platform',required=True)
parser.add_argument('--foo')
parser.add_argument('--bar')
parser.add_argument('--baz')
args = parser.parse_args()
if args.platform == 'A':
assert args.baz is None, "no argument baz for the platform A"
...
使用del
使用del
排除不需要的参数:
parser = argparse.ArgumentParser()
parser.add_argument('--platform',required=True)
parser.add_argument('--foo')
parser.add_argument('--bar')
parser.add_argument('--baz')
args = parser.parse_args()
if args.platform == 'A':
del args.baz
...
我不建议您在同一脚本中使用argparse
和sys.argv
,因为在您的情况下它们是出于相同的目的。最好选择其中之一。
argparge
在脚本知道值之前解析参数。因此,您不能根据其中一个参数的值来更改参数列表。因此,如果要保留argparse
,则必须将整个参数集与.add_argument
相加,并在获得值时在下面做一些额外的事情。