Python Argparse建议帮助文本使用行中的无意义顺序

Python Argparse建议帮助文本使用行中的无意义顺序,python,parameter-passing,argparse,Python,Parameter Passing,Argparse,该计划: import argparse parser = argparse.ArgumentParser() parser.add_argument('files', metavar='INPUT', nargs='*', help='File(s) containing words to include. If none given, stdin will be used.') parser.add_argument('-x', '--exclude', nargs='*',

该计划:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('files', metavar='INPUT', nargs='*',
    help='File(s) containing words to include. If none given, stdin will be used.')
parser.add_argument('-x', '--exclude', nargs='*',
    help='File(s) containing words to exclude.')
args = parser.parse_args()
print args.files
print args.exclude
在Python 2.7.9中运行时生成此输出:

$python prog.py--帮助
用法:prog.py[-h][-x[EXCLUDE[EXCLUDE…]]][INPUT[INPUT…]]
位置参数:
包含要包含的单词的输入文件。如果
未给出,将使用标准DIN。
可选参数:
-h、 --帮助显示此帮助消息并退出
-x[EXCLUDE[EXCLUDE…]],--EXCLUDE[EXCLUDE[EXCLUDE…]]
包含要排除的单词的文件。
但是,该“帮助”输出指示用户对参数使用无意义的排序。这是毫无意义的,因为如果使用
-x
选项,则不会检测到
输入
参数

Argparse应该建议用户使用以下顺序:

usage: prog.py [-h] [INPUT [INPUT ...]] [-x [EXCLUDE [EXCLUDE ...]]]
两个问题:

  • 这是
    argparse
    中的错误吗?(我想是的。)
  • 不管它是否是一个bug,我如何修复它,以便
    $python prog.py--help
    将输出我想要的帮助文本(见上文),最好以尽可能好的方式输出

  • 最简单的方法是将
    usage=“…”
    添加到
    argparse.ArgumentParser()

    通过查看argparse的源代码,我找到了一种使用可能有点脏的参数的方法:

    class MyHelpFormatter(argparse.HelpFormatter):
    
        def _format_actions_usage(self, actions, groups):
            actions.sort(key=lambda a: bool(a.option_strings and a.nargs != 0))
            return super(MyHelpFormatter, self)._format_actions_usage(actions, groups)
    
    parser = argparse.ArgumentParser(formatter_class = MyHelpFormatter)
    
    '-f','--files'
    添加到输入选项:

    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--files', metavar='INPUT', nargs='*', required=True,
        help='File(s) containing words to include. If none given, stdin will be used.')
    parser.add_argument('-x', '--exclude', nargs='*',
        help='File(s) containing words to exclude.')
    args = parser.parse_args()
    print args.files
    
    显示:

    usage: argparse_test.py [-h] [-f [INPUT [INPUT ...]]]
                        [-x [EXCLUDE [EXCLUDE ...]]]
    
    optional arguments:
      -h, --help            show this help message and exit
      -f [INPUT [INPUT ...]], --files [INPUT [INPUT ...]]
                            File(s) containing words to include. If none given,
                            stdin will be used.
      -x [EXCLUDE [EXCLUDE ...]], --exclude [EXCLUDE [EXCLUDE ...]]
                        File(s) containing words to exclude.
    print args.exclude
    
    您可以使“文件”成为必需的。从文档中:

    一般来说,argparse模块假定-f和--bar等标志表示可选参数,这些参数在命令行中总是可以忽略。要使选项成为必需选项,可以为required=关键字参数指定True以添加_参数():


    生成
    用法
    行时,标记的参数放在第一位,位置放在第二位。这符合常见的命令行用法。它没有努力评估这是否是最佳选择

    解决这个问题的最简单方法是提供一个自定义的
    用法
    参数

    (关于更改使用行中参数的顺序,存在很多问题。解决方案需要自定义
    HelpFormatter
    类。 )

    正如您所注意到的,当*位置放置在*可选之后时,所有参数都被指定给可选。您可以使用
    '-'
    分隔两个参数列表

    positional
    采用已知数量的参数(例如默认参数)时,修补程序存在一个bug/问题,应该可以改进处理。它这样做是因为注意到位置需要一个参数,所以它为它保留了一个参数。但是在
    **
    的情况下,
    位置的
    不满足于none,因此它无法知道如何在2之间分割参数


    我喜欢将
    positional
    转换为标记参数的想法。这将减少大量
    *
    参数中固有的模糊性。

    谢谢。这为我提供了问题2的答案。它不理想,因为它不干燥:每次添加/删除参数时,我都必须更新它。关于问题1有什么想法吗?@sampablokuper:更新了一条去度假的路。我认为它可以被称为bug.eph,它已经够脏了,以至于我还不能完全理解它是如何工作的:)不过,很好的工作实现了对使用文本的重新排序;谢谢你的支持!只需使用
    required=True
    将其设置为必填项即可。谢谢<代码>输入是必须的,这就是为什么我一开始没有这么做的原因。OTOH,提供来自一个或多个文件的输入是可选的,所以也许我应该这样做。嗯,我会再考虑一下:)argparse的目的是减少程序员在(生成帮助文本)解析命令行参数时的负担。如果argparse将“自动”生成使用行,那么默认情况下它应该做正确的事情。无论如何,在所有有意义的情况下,让它把标记的参数放在第一位,但在毫无意义的情况下,它绝对不应该这样做,因为这对程序员几乎没有多大帮助。程序员不应该与他/她的工具抗争。这就是为什么我认为这是一个错误。谢谢你回答我的两个问题:)欢迎你提交一个补丁来纠正这个问题。生成使用线的方法相当长且脆弱。这需要一些改进。