Python argparse 需要选项,取决于定义的标志 [英] Python argparse requiring option, depending on the defined flags

查看:42
本文介绍了Python argparse 需要选项,取决于定义的标志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小的 python 脚本,它使用 argparse 让用户定义选项.它为不同的模式使用两个标志和一个让用户定义文件的参数.请参阅下面的简化示例:

I have a small python script, which uses argparse to let the user define options. It uses two flags for different modes and an argument to let the user define a file. See the simplified example below:

#!/usr/bin/python3

import argparse
from shutil import copyfile

def check_file(f):
    # Mock function: checks if file exists, else "argparse.ArgumentTypeError("file not found")"
    return f

def main():
    aFile = "/tmp/afile.txt"

    parser = argparse.ArgumentParser(description="An example",formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("-f", "--file", help="A file, used with method A.", default=aFile, type=check_file)
    parser.add_argument("-a", "--ay", help="Method A, requires file.", action='store_true')
    parser.add_argument("-b", "--be", help="Method B, no file required.", action='store_true')

    args = parser.parse_args()
    f = args.file
    a = args.ay
    b = args.be

    if a:
        copyfile(f, f+".a")
    elif b:
        print("Method B")

if __name__ == "__main__":
    main()

方法 A 需要文件.

方法 B 没有.

如果我使用方法 A 运行脚本,我要么使用默认文件,要么使用用 -f/--file 定义的文件.脚本检查文件是否存在并且一切正常.

If I run the script with method A, I either use the default file or one that is defined with -f/--file. The script checks if the file exists and everything is fine.

现在,如果我使用方法 B 运行脚本,它不应该需要该文件,但会选中默认选项,如果它不存在,则 argparse 函数会引发异常并退出脚本.

Now, if I run the script with method B, it shouldn't require the file, but the default option is checked and if it doesn't exist the argparse function raises the exception and the script exits.

如果定义了 -b 并且需要它,如果定义了 -a,我如何配置 argparse 以使 -f 可选?

How can I configure argparse to make -f optional, if -b is defined and require it, if -a is defined?

我刚刚意识到让 -f-b 相互排斥就足够了.但是,如果我只运行 -b,无论如何都会执行 check_file.有什么办法可以防止吗?

edit: I just realized that it would be enough for me to make -f and -b mutually exclusive. But then, if I run -b only, the check_file is executed anyways. Is there a way to prevent that?

#!/usr/bin/python3

import argparse
from shutil import copyfile

def check_file(f):
    # Mock function: checks if file exists, else "argparse.ArgumentTypeError("file not found")"
    print("chk file")
    return f

def main():
    aFile = "/tmp/afile.txt"

    parser = argparse.ArgumentParser(description="An example",formatter_class=argparse.RawTextHelpFormatter)
    group = parser.add_mutually_exclusive_group(required=True)

    group.add_argument("-f", "--file", help="A file, used with method A.", default=aFile, type=check_file)
    parser.add_argument("-a", "--ay", help="Method A, requires file.", action='store_true')
    group.add_argument("-b", "--be", help="Method B, no file required.", action='store_true')

    args = parser.parse_args()
    f = args.file
    a = args.ay
    b = args.be

    if a:
        print("File: "+str(f))
    elif b:
        print("Method B")
        print("file: "+str(f))

if __name__ == "__main__":
    main()

输出:

chk file
Method B
file: /tmp/afile.txt

推荐答案

您可以使用 ay/be 定义子解析器作为子命令,或者为 a 声明第二个解析器实例.类似的东西:

You can defined subparser with ay/be as subcommand or alternatively declare a second parser instance for a. Something like:

parser = argparse.ArgumentParser(
    description="An example",
    formatter_class=argparse.RawTextHelpFormatter
)
# ensure either option -a or -b only
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("-a", "--ay", help="Method A, requires file.",
                   action='store_true')
group.add_argument("-b", "--be", help="Method B, no file required.",
                   action='store_true')
# define a parser for option -a
parser_a = argparse.ArgumentParser()
parser_a.add_argument("-f", "--file", help="A file, used with method A.",
                      type=check_file, required=True)
parser_a.add_argument("-a", "--ay", help="Method A, requires file.",
                      action='store_true')

# first parse - get either -a/-b
args = parser.parse_known_args(sys.argv[1:])
# if -a, use the second parser to ensure -f is in argument
# note parse_known_args return tuple, the first one is the populated namespace
if args[0].ay:
    args = parser_a.parse_args(sys.argv[1:])

这篇关于Python argparse 需要选项,取决于定义的标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆