我有一个小的 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/