python - 定义不同形式的 argparse 参数输入

标签 python argparse

我刚刚开始使用 argparse ,我的代码可以工作,但我试图解析不同的值以了解用户如何在参数中键入。

目前这是我的代码:

def setup_args():
    """
    Set up args for the tool
    """
    parser = argparse.ArgumentParser(
        description=("Get all file versions of a status in a project"),
        formatter_class=argparse.RawDescriptionHelpFormatter)

    # Positional Arguments
    parser.add_argument('project',
                        type=str,
                        help='Name of the to look into')

    parser.add_argument('status',
                        type=str,
                        help='Define which status to look into')

    # Optional Arguments
    parser.add_argument('-o',
                        '--output',
                        action='store_true',
                        help='Write to output to text file if used')

if __name__ == "__main__":
    args = setup_args()

    # Check the status set
    status_list = ['Pending', 'Work in Progress', 'Approved', 'Rejected']
    if not args.status in site_list:
        raise ValueError("Please input one of the status : 'Pending', 'Work in Progress', 'Approved', 'Rejected'")

    output_query(args.project, status, args.client, args.output)

正如您在我的 main 中看到的那样..它只注册我定义的那些区分大小写的状态名称。 如果我的代码以小写大写字母输入,是否有任何方法可以让我的代码进行注册 - 'pending', 'work in progress', 'approved', 'rejected'或简称 - 'p', 'wip', 'a', 'r'

我可以实现的方法之一是使用 if..elif..

if args.client == ('pending' or 'p'):
    args.client = 'Pending'
elif args.client == ('work in progress' or 'wip'):
    args.client = 'Work in Progress'
elif args.client == ('approved' or 'a'):
    args.client = 'Approved'
elif args.client == ('rejected' or 'r'):
    args.client = 'Rejected'

虽然它有效,但对我来说看起来有点“啰嗦”。如果我有多个参数,这意味着我需要输入大量 if...elif...除非这是唯一的方法,否则这可能不切实际。 有没有更好的解决方案来解决这个问题?

编辑:

这就是我运行命令的方式:python prog.py my_project Pending 但我正在考虑可以这样输入的场景:python prog.py my_project pendingpython prog.py my_project p ,请注意大写字母 P 已变成小写字母..

最佳答案

您可以使用 .lower() 概括 status 检查并限制检查的字符数。

例如,如果我定义一个“选择”的缩写列表,我可以使用以下命令测试任何看起来像大牌的东西:

In [239]: choices = ['pend', 'work', 'appr','reje']
In [240]: status_list = ['Pending', 'Work in Progress', 'Approved', 'Rejected']
In [241]: for wd in status_list:
     ...:     if wd.lower()[:4] in choices:
     ...:         print(wd)
     ...:         
Pending
Work in Progress
Approved
Rejected

您可能不应该期望您的用户输入完整的“正在进行的工作”字符串。为此,需要引用。否则 shell 会将其分成 3 个字符串。

此测试的一个变体使用 startswith:

for wd in status_list:
     if any([wd.lower().startswith(n) for n in choices]):
         print(wd)

您还可以让解析器进行值检查

parser.add_argument('status',
                    # type=str,   # default, don't need to add it
                    choices = ['pending', 'work', 'approved', 'rejected'],
                    help='Define which status to look into')

如果字符串不匹配,则会生成一条不错的错误消息。它将选项合并到帮助中。尝试一下,看看会发生什么。

缺点是它不允许缩写或大小写。 (自定义 type 函数可以绕过这些限制,但这是一种更高级的技术)。

==================

使用type的一种方法是定义一个小函数:

def abrev(astr):
    return astr.lower()[:4]

在上述测试中有效:

for wd in status_list:
    if abrev(wd) in choices:
        print(wd)

在解析器中它可以用作:

In [253]: p = argparse.ArgumentParser()
In [254]: p.add_argument('status', type=abrev, choices=choices);

In [255]: p.print_help()
usage: ipython3 [-h] {pend,work,appr,reje}

positional arguments:
  {pend,work,appr,reje}

optional arguments:
  -h, --help            show this help message and exit

调用示例:

In [256]: p.parse_args(['Work'])
Out[256]: Namespace(status='work')

In [257]: p.parse_args(['status'])
usage: ipython3 [-h] {pend,work,appr,reje}
ipython3: error: argument status: invalid choice: 'stat' (choose from 'pend', 'work', 'appr', 'reje')
...

In [258]: p.parse_args(['reject'])
Out[258]: Namespace(status='reje')

In [259]: p.parse_args(['Pending'])
Out[259]: Namespace(status='pend')

关于python - 定义不同形式的 argparse 参数输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41771359/

相关文章:

Python - 填写登录表单,然后填写只有登录后才能访问的另一个表单

python - 如何在我的代码中传递全局调试标志变量;我应该使用 argparse 吗?

python - 使用 argparse 的 `add_subparsers` 方法实现两个位置参数

Python 名称错误 : name 'file_name' is not defined

Python 和 argparse : how to vary required additional arguments based on the first argument?

python - 如何在 KivyMD (Python) 中组合抽屉导航和多个屏幕?

python - 从 Visual Studio Code 中运行 python 时出现无效语法错误

python - 引发异常后继续执行循环

python - 去除 Python 字符串中某些 html 标签的最快方法是什么?

python - argparse 不转换默认数字参数?