32

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

$ python3 myprog.py -i infile -o outfile
$ python3 myprog.py -o outfile
$ python3 myprog.py -o
$ python3 myprog.py 

特别是我想让指定输入文件而不是输出文件是非法的。

在第三种情况下,假定输出文件的默认名称为“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

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

4

2 回答 2

22

作为所选答案的附加内容:

在不指定文件的情况下运行的选项-o可以使用constnargs='?'.

文档

当使用选项字符串(如 -f 或 --foo)和 nargs='?' 调用 add_argument() 时。这将创建一个可选参数,后面可以跟零个或一个命令行参数。解析命令行时,如果遇到选项字符串后没有命令行参数,则将假定 const 的值。有关示例,请参见 nargs 描述。

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

parser.add_argument('-o', '--outfile', nargs='?', const='arg_was_not_given', help='output file, in JSON format')

args = parser.parse_args()

if args.outfile is None:
    print('Option not given at all')
elif args.outfile == 'arg_was_not_given':
    print('Option given, but no command-line argument: "-o"')
elif:
    print('Option and command-line argument given: "-o <file>"')
于 2014-01-06T13:23:36.460 回答
18

您为 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_file = args.out if args.out is not None else 'json.out'

如果您指定不带参数的 ,我不确定相关参数是否为Noneor ''(即空字符串)-o——我怀疑它是None,但我不确定。您必须对其进行测试才能确定。

如果没有使用 argparse 的额外逻辑,我不知道如何做到这一点。

于 2013-04-02T00:52:42.750 回答