Python argparse 需要选项,具体取决于定义的标志

标签 python arguments parameter-passing argparse optional-parameters

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

#!/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 定义的文件。该脚本检查文件是否存在以及是否一切正常。

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

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

编辑: 我刚刚意识到让 -f-b 互斥就足够了。但是,如果我只运行 -b,无论如何都会执行 check_file。有什么办法可以避免吗?

#!/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 声明第二个解析器实例。像这样的东西:

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 需要选项,具体取决于定义的标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43134549/

相关文章:

iphone - 何时释放/保留传递给辅助线程的对象?

javascript - 无法在 JavaScript 中的可变长度参数数组上运行函数

Android:如何解决来自服务的 Google API 连接失败?

javascript - 从 javascript 调用 codeigniter 方法并传递数据

postgresql - 合并多个结果表并对结果进行最终查询

python - Django - 如何在多个表单上使用完全相同的 clean() 方法

python - 以编程方式确定 Bin 路径

python - 在python中分配一个列表

python - Pandas groupby 应用如何加速

c++ - 为什么按值传递 string_view?为什么 Visual Studio 不能对此进行优化?