在 Python 脚本中采用命令行参数的最佳方式
Posted
技术标签:
【中文标题】在 Python 脚本中采用命令行参数的最佳方式【英文标题】:Best way to take Command Line Arguments in Python Script 【发布时间】:2022-01-06 20:00:47 【问题描述】:在我的 Python 脚本中,我有很多命令行参数。其中一些是强制性的,而另一些是可选的。对于某些强制参数的值,一些可选参数也是强制的。在这种命令行参数的情况下,最好的方法是什么。我使用argparse.Argumentparser
来达到我的目的。
为了阐明用例,这里有一个例子。假设我有 3 个强制参数:mode, foo, bar
和 5 个可选参数:op1, op2, op3, op4, op5
。可以说,mode
可以有 3 个值:m1, m2, m3
。如果mode
是m1
,则op1 and op2
是强制性的。如果mode
是m2
,op3
是强制性的,如果mode
是m3
,op4 and op5
是强制性的。
将它放入代码的最佳方式是什么?我现在所做的似乎过于详尽,只是觉得必须有更好的方法来做到这一点。
-> 当前代码
import argparse
# create and execute parser
my_parser = argparse.ArgumentParser(description="Demo")
my_parser.add_argument("--mode", action="store", type=str, required=True)
my_parser.add_argument("--foo", action="store", type=str, required=True)
my_parser.add_argument("--bar", action="store", type=str, required=True)
my_parser.add_argument("--op1", action="store", type=str, required=False, default=None)
my_parser.add_argument("--op2", action="store", type=str, required=False, default=None)
my_parser.add_argument("--op3", action="store", type=str, required=False, default=None)
my_parser.add_argument("--op4", action="store", type=str, required=False, default=None)
my_parser.add_argument("--op5", action="store", type=str, required=False, default=None)
args = my_parser.parse_args()
try:
if args.mode == "m1":
op1 = args.op1.lower()
op2 = args.op2.lower()
if args.mode == "m2":
op3 = args.op3.split(',')
if args.mode == "m3":
op4 = args.op4.lower()
op5 = args.op5.lower()
except AttributeError:
print("Wrong mode set for optional arguments")
exit()
如您所见,即使是这个示例在美学上也只是“看起来”很糟糕(尤其是 try
块解析),而且我有很多可选参数需要处理。任何帮助将不胜感激。
此外,这种方法并不完全强制用户输入,例如,op1 and op2
,以防他的mode=m1
。如果也有可能做这样的事情,那对我来说将是额外的好处。
谢谢。
【问题讨论】:
【参考方案1】:您的程序似乎正在处理多个不同的任务。支持这一点的方法是将解析器拆分为sub-commands:
import argparse
parser = argparse.ArgumentParser(description="Demo")
parser.add_argument("--foo", required=True)
parser.add_argument("--bar", required=True)
subparsers = parser.add_subparsers(dest='mode', required=True)
m1_parser = subparsers.add_parser('m1', help='mode 1')
m1_parser.add_argument("--op1", required=True)
m1_parser.add_argument("--op2", required=True)
m1_parser.add_argument("--op3")
m1_parser.add_argument("--op4")
m1_parser.add_argument("--op5")
m2_parser = subparsers.add_parser('m2', help='mode 2')
m2_parser.add_argument("--op1")
m2_parser.add_argument("--op2")
m2_parser.add_argument("--op3", required=True)
m2_parser.add_argument("--op4")
m2_parser.add_argument("--op5")
m3_parser = subparsers.add_parser('m3', help='mode 3')
m3_parser.add_argument("--op1")
m3_parser.add_argument("--op2")
m3_parser.add_argument("--op3")
m3_parser.add_argument("--op4", required=True)
m3_parser.add_argument("--op5", required=True)
args = parser.parse_args()
if args.mode == 'm1':
print(args.op1) # it will always exist
用法:
$ python3 args.py m1
usage: args.py m1 [-h] --op1 OP1 --op2 OP2 [--op3 OP3] [--op4 OP4] [--op5 OP5]
args.py m1: error: the following arguments are required: --op1, --op2
虽然这似乎是重复的,但您现在可以选择为特定于子命令的各种选项提供更好的名称。
【讨论】:
这里,m1
似乎是常见的 args
参数,而不是 argparse 给出的键控参数。是否有可能有类似:python3 args.py --mode m1
被子解析器读取?
我添加了一种方法来检查所选的特定模式。这是否回答你的问题?您也可以将required=True
添加到add_subparsers()
以确保模式存在。
但是我如何为这个脚本添加foo
和bar
,我的强制参数(我需要与mode
一起提供)?
它们可以添加到主解析器中,就像您之前所做的那样。我扩展了我的答案。
@vish4071 完成!以上是关于在 Python 脚本中采用命令行参数的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章