argparse 中不同级别的帮助详细程度

Different levels of help verbosity in argparse

我有一个包含几十个 CLI 参数的应用程序。我使用 python argparse 来解析参数。其中大部分很少使用,只有 5 或 6 个经常使用。对于简单的情况,我不想弄乱 --help 的输出,但是仍然应该有可能以某种方式查看所有参数的描述。

在 argparse 中可以有多个详细级别来寻求帮助吗?这是我期望的样子。

$ myapp -h
optional arguments:
 --foo         Do foo stuff
 --bar         Do bar stuff

$ myapp -hh # or myapp --expert-mode -h
optional arguments:
  --foo         Do foo stuff
  --bar         Do bar stuff

expert arguments:
  --use-warp-drive
  --no-fasten-seatbelts
... 50 more arguments

我的第一个想法是创建两个 ArgumentParser-s,基本的和详细的。首先,调用了基本的parse_args。如果存在 --expert 标志,则会创建并调用详细解析器。该方法有两个缺点。首先,-h 由第一个解析器无条件处理,因此我应该实现自己的类似帮助标志。其次,没有 --expert 标志甚至不会解析专家选项,我希望无条件地解析它们(但不要弹出帮助)。

注意:解决方案应 python2 兼容。


更新:使用 Lior Cohen 的回答和 问题中的想法,我创建了一个工作示例。在我的例子中,创建一个“简单”选项的白名单更容易,所以甚至没有必要使用标记的操作类型。

说明代码如下。

class ExpertHelpFormatter(argparse.HelpFormatter):
    skip_expert_section = True
    whitelist = set(("foo",))

    def add_usage(self, usage, actions, groups, prefix=None):
        if self.skip_expert_section:
            actions = [action for action in actions if action.dest in self.whitelist]
        ret = super(ExpertHelpFormatter, self).add_usage(usage, actions, groups, prefix)
        if self.skip_expert_section:
            self.add_text("Use -hh for detailed help.")
        return ret

    def add_argument(self, action):
        if self.skip_expert_section and action.dest not in self.whitelist:
            return
        super(ExpertHelpFormatter, self).add_argument(action)

def main():
    parser = argparse.ArgumentParser(add_help=False, formatter_class=ExpertHelpFormatter)

    parser.add_argument("-h", "--help", action="count", default=0)
    parser.add_argument("--foo")
    parser.add_argument("--use-warp-drive", action="store_true")

    args = parser.parse_args()

    if args.help == 1:
        print parser.format_help()
        return
    elif args.help > 1:
        ExpertHelpFormatter.skip_expert_section = False
        print parser.format_help()
        return

这里的布局应该可以满足您的需求,但它并不是“免费工作”。

  1. 通过 add_help = False 禁用默认帮助(参见 here)。这将使您仍然可以使用 -h--help 来执行您想要的操作。
  2. 您需要通过 type 来“标记”您的专家论点,这将以某种方式存储 foo 是“简单”而 use-warp-drive 是“专家”这一事实。您可以向 Action 添加属性或在解析器本身中保存全局字典。
  3. 写一个Help Formatter(可以看看example)。然后,根据上面的“标签”,如果是“简单”模式,您可以通过返回""来抑制“专家”帮助。

希望这对您有所帮助。