Python argparse: nargs='?' 和可选参数

6
假设我有一个名为readfile.py的简单程序,它使用Python的argparse支持命令行参数。该程序从由位置参数input指定的文件中读取数据。如果没有指定附加参数,该程序并不是很有趣。它只是从input中读取数据并退出。可选参数--output [OUTPUT_FILE]表示应将输入文件写入文件中,而OUTPUT_FILE也是可选的。如果未指定,则应将输入写入default.out文件中。
我像这样设置了参数解析器:
parser = argparse.ArgumentParser(description='Read from a file')
parser.add_argument(
    'input',
    help='file to read from')
parser.add_argument(
    '--output',
    nargs='?',
    const='default.out',
    default=None,
    help="""write file to %(metavar)s. If %(metavar)s isn't
         specified, write file to %(const)s.""",
    metavar='OUTPUT_FILE')
args = parser.parse_args()
return args.file, args.output_file

请注意,我使用default = None,这样如果命令行中没有--ouput出现,我可以将其缺失检测为None。
这将给出以下用法签名:
usage: readfile.py [-h] [--output [OUTPUT_FILE]] input

如果我运行这个命令,它会按预期处理参数

python readfile.py input.in --output somefile.out

或者

python readfile.py --output somefile.out input

如果我运行,它会将output设置为default.out
python readfile.py input.in --output

但如果我运行

python readfile.py --output input.in

程序报错,指出参数不足。我原以为argparse会“智能”地解释这种模式,并将input设置为input.in,将output设置为default.out。生成的用法甚至表明了这一点。

我是不是漏掉了什么?


2
谁给这个问题点了踩,至少应该在评论中留下一些建设性的提示。 - cfi
2个回答

6
不会识别这个。在最后一个例子中,您明显将 input.in 传递给了 --output
我建议您交换 defaultconst 参数。您希望默认值为 default.out,因此应该是 default='default.out'。对于空的 --output 参数,可以将 const 设置为其他值。
这样,除非您想更改默认设置,否则不必添加 --output 参数,并且如果要将输出发送到 stdout,则可以使用空的 --output 参数。

在这种情况下(令人困惑的是?),default用于--output后没有参数,而const用于完全没有--output参数的情况。 - eidorb
@eidorb:是的,而且这还是反过来的。把它改过来。按照它应该使用的方式使用它。 - Lennart Regebro
我必须道歉。我的评论是反过来的,但我的代码是我想要的方式。 - eidorb
@eidorb:这是反过来的。把它改正过来,按照它应该使用的方式使用。认真对待。 - Lennart Regebro

0
您可以传递“--”来标记任何选项的结束。例如:
python readfile.py --output -- input

具有预期效果。然而,将参数设置为--output为必需,并允许:

python readfile.py --output - input

可能更加简洁。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接