SaA*_*mic 2 python arguments parameter-passing optional-parameters argparse
我有一个小的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()
Run Code Online (Sandbox Code Playgroud)
方法A需要该文件。
方法B没有。
如果使用方法A运行脚本,则将使用默认文件或使用-f/ 定义的文件--file。该脚本检查文件是否存在,并且一切正常。
现在,如果我使用方法B运行脚本,则该脚本不需要该文件,但是将检查默认选项,并且如果不存在该默认选项,则argparse函数将引发异常并退出脚本。
如何配置argparse以使其成为-f可选(如果-b已定义)并要求它(如果-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()
Run Code Online (Sandbox Code Playgroud)
输出:
chk file
Method B
file: /tmp/afile.txt
Run Code Online (Sandbox Code Playgroud)
小智 5
您可以使用y / 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:])
Run Code Online (Sandbox Code Playgroud)