如何在python argparse中使参数可选

如何在python argparse中使参数可选,python,argparse,Python,Argparse,我想让这些调用myprog工作,而不是其他调用 $ python3 myprog.py -i infile -o outfile $ python3 myprog.py -o outfile $ python3 myprog.py -o $ python3 myprog.py 特别是,我想将指定填充文件而不是输出文件设置为非法 parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), defa

我想让这些调用myprog工作,而不是其他调用

$ python3 myprog.py -i infile -o outfile
$ python3 myprog.py -o outfile
$ python3 myprog.py -o
$ python3 myprog.py 
特别是,我想将指定填充文件而不是输出文件设置为非法

parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format')
在第三种情况下,输出文件的默认名称为“out.json”。在第二种、第三种和第四种情况下,输入文件的默认名称为“file.n.json”,其中n是一个整数版本号。在第四种情况下,输出文件将是“file.n+1.json”,其中n+1是比输入文件上的版本号大的版本号。我的代码的相关部分是:

import argparse

parser = argparse.ArgumentParser(description="first python version")
parser.add_argument('-i', '--infile', nargs=1, type=argparse.FileType('r'), help='input file, in JSON format')
parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format')

args = parser.parse_args()

print("Here's what we saw on the command line: ")
print("args.infile",args.infile)
print("args.outfile",args.outfile)

if args.infile and not args.outfile:
    parser.error("dont specify an infile without specifying an outfile")
elif not args.infile:
    print("fetching infile")
else: # neither was specified on the command line
    print("fetching both infile and outfile")
问题是,当我跑步的时候

$ python3 myprog.py -i infile.json
我得到的不是我所希望的解析器错误,而是:

Here's what we saw on the command line: 
args.infile [<_io.TextIOWrapper name='infile.json' mode='r' encoding='UTF-8'>]
args.outfile <_io.TextIOWrapper name='out.json' mode='w' encoding='UTF-8'>
fetching both infile and outfile
下面是我们在命令行上看到的内容:
args.infle[]
args.outfile
同时获取填充文件和输出文件

…这表明,即使命令行上没有“-o”,它的行为也好像有一样。

您为outfile指定了一个默认参数

parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format')
如果未在命令行中指定
-o
选项,则arg解析器将插入默认参数

将此更改为:

parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), help='output file, in JSON format')
事情应该按照你的预期进行


如果您希望能够指定
-o
,而不需要文件名,则可能需要以下内容:

out\u file=args.out,如果args.out不是其他任何“json.out”

如果您指定的
-o
没有参数,我不确定相关参数是
None
还是
'
(即空字符串)——我怀疑它是
None
,但我不确定。你必须测试一下才能确定


如果没有argparse的额外逻辑,我不知道如何执行此操作。

作为所选答案的附加:

在不指定文件的情况下运行
-o
的选项可以使用
const
nargs='?'
组合来完成

从:

使用选项字符串(如-f或--foo)调用add_argument()时 而nargs=“?”。这将创建一个可选的参数,可以遵循该参数 通过零个或一个命令行参数。在分析命令行时, 如果遇到没有命令行参数的选项字符串 在此之后,将假定const的值。见 nargs示例说明

示例(使用类型字符串):

parser.add_参数('-o','-outfile',nargs='?',const='arg_'was_not_given',help='output file,JSON格式')
args=parser.parse_args()
如果args.outfile为无:
打印('完全未给出选项')
elif args.outfile=='arg\u未\u给定':
print('给出了选项,但没有命令行参数:“-o”')
埃利夫:
print('给定选项和命令行参数:“-o”')

第三种情况和第四种情况有什么区别?-o代表什么?第四种情况将使用默认的infile和outfile名称(特别是file.n.json和file.n+1.json,即嵌入版本号的文件)。这些与“out.json”不同,后者是使用“-o”选项的第三种情况所导致的结果。我修改了上面的文本来说明这一点。第4个案例应该如何工作,因为
--input
选项没有默认值?这几乎正是我想要的。剩下的问题是,我希望
$python3myprog.py-o
像运行
$python3myprog.py-o out.json一样运行。你能建议怎么做吗?谢谢!我原以为我可以用argparse来做。这个答案忽略了问题中第三个案例的要求。关于如何使用argparse实现第三种情况,请参见maximi的答案。最后一个赋值甚至不是有效的Python语法。