Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按字母顺序对argparse帮助进行排序_Python_Sorting_Arguments_Command Line Arguments_Argparse - Fatal编程技术网

Python 按字母顺序对argparse帮助进行排序

Python 按字母顺序对argparse帮助进行排序,python,sorting,arguments,command-line-arguments,argparse,Python,Sorting,Arguments,Command Line Arguments,Argparse,我正在使用Python的(2.7)argparse工具,并希望自动按选项的字母顺序对它生成的帮助进行排序 默认情况下,帮助条目按添加顺序排序*,如下所示: p = argparse.ArgumentParser(description='Load duration curves and other plots') p.add_argument('--first', '-f', type=int, default=1, help='First Hour') p.add_argument('--du

我正在使用Python的(2.7)argparse工具,并希望自动按选项的字母顺序对它生成的帮助进行排序

默认情况下,帮助条目按添加顺序排序*,如下所示:

p = argparse.ArgumentParser(description='Load duration curves and other plots')
p.add_argument('--first', '-f', type=int, default=1, help='First Hour')
p.add_argument('--dur', '-d', type=int, default=-1, help='Duration in Hours. Use -1 for all')
p.add_argument('--title', '-t', help='Plot Title (for all plots), default=file name')
p.add_argument('--interp', '-i', action="store_true", default=True, 
                help='Use linear interpolation for smoother curves')
...
args = p.parse_args()
当被称为
python脚本-h
时,会生成:

usage: script.py [-h] [--first FIRST] [--dur DUR] [--title TITLE] [--interp]

Load duration curves and other plots

optional arguments:
  -h, --help            show this help message and exit
  --first FIRST, -f FIRST
                        First Hour
  --dur DUR, -d DUR     Duration in Hours. Use -1 for all
  --title TITLE, -t TITLE
                        Plot Title (for all plots), default=file name
  --interp, -i          Use linear interpolation for smoother curves
是否可以改为按字母顺序自动排序?这将是dur,first,h,interp,title


*显然,解决方法是通过按字母顺序添加p.add_参数来手动维护条目,但我试图避免这样做。

创建ArgumentParser类时,可以传入帮助格式化程序:

显然,您可以使用其中一个提供的格式化程序,但如果不进行反向工程,就无法覆盖和替换它们:

>>> h = argparse.ArgumentDefaultsHelpFormatter
>>> print h.__doc__
Help message formatter which adds default values to argument help.

    Only the name of this class is considered a public API. All the methods
    provided by the class are considered an implementation detail.

您可以通过提供一个自定义的;其内部内容没有正式记录。这意味着,在Python版本之间的兼容性问题上,您只能依靠自己,但我发现该界面相当稳定:

from argparse import HelpFormatter
from operator import attrgetter

class SortingHelpFormatter(HelpFormatter):
    def add_arguments(self, actions):
        actions = sorted(actions, key=attrgetter('option_strings'))
        super(SortingHelpFormatter, self).add_arguments(actions)


p = argparse.ArgumentParser(...
    formatter_class=SortingHelpFormatter,
)
在这里,我根据选项字符串(
('-dur','-d')
等)进行排序,但您可以选择要排序的内容。这个简单的排序选项将单破折号选项放在最后,就像
-h
选项一样

哪些产出:

usage: [-h] [--first FIRST] [--dur DUR] [--title TITLE] [--interp]

Load duration curves and other plots

optional arguments:
  --dur DUR, -d DUR     Duration in Hours. Use -1 for all
  --first FIRST, -f FIRST
                        First Hour
  --interp, -i          Use linear interpolation for smoother curves
  --title TITLE, -t TITLE
                        Plot Title (for all plots), default=file name
  -h, --help            show this help message and exit
一种比@MartijnPieters提出的更丑陋的替代方法:

p = argparse.ArgumentParser()

#add arguements here

for g in p._action_groups:
    g._group_actions.sort(key=lambda x:x.dest)

把它放在
try
/
子句中可能会很好,因为它只是格式化帮助,因此如果这段代码在
属性错误上失败,那么它对程序的执行并不重要。我以为我之前已经发布了这个,但显然没有

d = dict()
d['--first'] = ('-f', "type=int", "default=1", "help='First Hour'")
d['--dur'] = ('-d', type=int, default=-1, help='Duration in Hours. Use -1 for all')
# etc

for prim_option in sorted(d):
    p.add_arguments(prim_option, *d[prim_option])

您可以调整字典中用作键的确切内容,以及
sorted
的参数和
add\u arguments
调用的确切结构,以获得所需的排序顺序。这符合公开文档化的接口
argparse
,但确实为定义解析器的过程添加了一层。(根据您的理念,将选项信息与解析器的实现分离可能是一件好事。)

帮助中的参数顺序由
解析器决定。format_help
方法:

Definition:  parser.format_help(self)
Source:
    def format_help(self):
        formatter = self._get_formatter()
        ...
        # positionals, optionals and user-defined groups
        for action_group in self._action_groups:
            formatter.start_section(action_group.title)
            formatter.add_text(action_group.description)
            formatter.add_arguments(action_group._group_actions)
            formatter.end_section()
help
是通过获取
formatter
对象,然后向其中添加“sections”来创建的。在这里,它循环遍历
\u action\u组
,将每个组放入自己的部分,并使用
add\u arguments
方法添加其操作(参数)。格式化程序是临时的,仅用于创建字符串(通常是多行)

操作组包括默认的
帖子
选项
,以及用户创建的任何内容。这些组仅用于帮助,不用于解析。因此,
action\u group.\u group\u actions
列表可以在不影响解析的情况下重新排序。(解析器有自己的操作列表,
parser.\u actions

这证实了@mgilson的观察,即排序
p.\u操作
不会影响帮助,但排序
\u组操作
会影响帮助

排序
\u操作
将影响
的使用
(无论是帮助的一部分还是独立的):

请注意,
action\u组
不会传递到用法部分。使用部分会对其操作进行重新排序,首先显示
选项
,然后显示
位置

如果要控制位置的解析顺序及其在用法中的顺序,请在
add_argument
阶段之前/期间对参数进行排序

如果您只想控制“帮助”组中的顺序,则可以在调用格式化程序之前或在格式化程序中,在
\u group\u actions
列表中重新排序

用法
中还有其他一些关于控制操作顺序的问题。例如,有些人不希望将
位置
排序在
选项
之后

我同意Formatter类是cumbersom。但在大多数情况下,它与解析器类是分开的。因此,它可以被重写,对解析的影响最小。现有的Formatter子类只是调整了低级方法,即控制换行和帮助行格式化的方法。解析器和格式化程序之间的重要接口是
format\u用法
format\u帮助
方法,它们相对简单且层次较高

子类化
尽管有@GREEF quotes的警告,人们还是会根据自己的需要对
HelpFormatter
进行子类化。唯一阻止人们这样做的是某种公司政策。所有的警告告诉我们,argparse开发人员没有尝试想象或记录用户可能想要做的所有更改。我甚至无法列举过去几年中我建议的参数。

我想你可以勾选p.show\u help或其他什么,然后手动解析参数列表。。。我会看看是否可以在上面找到文档……我经常认为应该向用户公开更多信息:-/(除了提供一些格式化程序,基本上不允许用户以任何方式干扰它们之外)--我认为这是因为代码非常难看而且很难编写,而argparse开发人员不想让用户受此约束。这是具有讽刺意味的,因为
argparse
的动机是扩展
optparse
代码库的丑陋和困难。
super(HelpFormatter
应该是
super)(SortingHelpFormatter
是否使用过添加参数(单数)的调用?@Grive:是的,它由
HelpFormatter.add_arguments()使用)
我覆盖的方法。@MartijnPieter很好,这很有意义。只是想知道未记录的API是否曾经绕过add_参数而支持add_参数。解释很清楚。我应该选择
    # usage
    formatter.add_usage(self.usage, self._actions,
                        self._mutually_exclusive_groups)