Python:argparse 帮助文本的分页?

Posted

技术标签:

【中文标题】Python:argparse 帮助文本的分页?【英文标题】:Python: Paging of argparse help text? 【发布时间】:2020-03-11 14:20:15 【问题描述】:

对于使用argparse 并且参数列表很长的Python 脚本,是否可以使argparse 页面在使用-h 选项调用脚本时打印到终端?

【问题讨论】:

可以使用格式化类docs.python.org/3/library/argparse.html#formatter-class @paltaa 好的;这如何帮助我对输出进行分页(我在您链接到的页面中看不到任何相关内容)? 一个好问题,但恕我直言,这是个坏主意。至少在 Linux/Unix 上,-h|--help 预计会打印帮助文本并退出。用户应决定是否需要寻呼机。例如,他/她可能想在终端窗口中向后滚动。另请注意,您必须处理重定向的输入/输出并仅在 tty 上启用寻呼机。我建议坚持通常的做法,以保持帮助文本简洁,并将所有详细信息放入手册页。或者每个子命令或主题都可以有自己的帮助。 @VPfB 我知道man shell 命令;你的意思是我可以让它显示我的脚本的帮助文本吗?怎么样? 使用parser.print_help 方法显示帮助,该方法将parser.format_help() 字符串发送到stdout。可以想象你可以在这里拼接寻呼机。但是在 shell 级别进行分页会更简单:python your_script.py -h | less 【参考方案1】:

我找不到快速的答案,所以我写了一些东西:

# hello.py
import argparse
import os
import shlex
import stat
import subprocess as sb
import tempfile


def get_pager():
    """
    Get path to your pager of choice, or less, or more
    """
    pagers = (os.getenv('PAGER'), 'less', 'more',)
    for path in (os.getenv('PATH') or '').split(os.path.pathsep):
        for pager in pagers:
            if pager is None:
                continue
            pager = iter(pager.split(' ', 1))
            prog = os.path.join(path, next(pager))
            args = next(pager, None) or ''
            try:
                md = os.stat(prog).st_mode
                if md & (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH):
                    return 'p a'.format(p=prog, a=args)
            except OSError:
                continue


class CustomArgParser(argparse.ArgumentParser):
    """
    A custom ArgumentParser class that prints help messages
    using either your pager, or less or more, if available.
    Otherwise, it does what ArgumentParser would do.
    Use the PAGER environment variable to force it to use your pager
    of choice.
    """
    def print_help(self, file=None):
        text = self.format_help()
        pager = get_pager()
        if pager is None:
            return super().print_help(file)
        fd, fname = tempfile.mkstemp(prefix='simeon_help_', suffix='.txt')
        with open(fd, 'w') as fh:
            super().print_help(fh)
        cmd = shlex.split('p f'.format(p=pager, f=fname))
        with sb.Popen(cmd) as proc:
            rc = proc.wait()
            if rc != 0:
                super().print_help(file)
            try:
                os.unlink(fname)
            except:
                pass


if __name__ == '__main__':
    parser = CustomArgParser(description='Some little program')
    parser.add_argument('--message', '-m', help='Your message', default='hello world')
    args = parser.parse_args()
    print(args.message)

这个 sn-p 做主要的事情。首先,它定义了一个函数来获取寻呼机的绝对路径。如果您设置环境变量PAGER,它将尝试使用它来显示帮助消息。其次,它定义了一个自定义类,它几乎继承了argparse.ArgumentParser 的所有内容。这里唯一被覆盖的方法是print_help。每当找不到有效的寻呼机时,它默认为super().print_help() 实现print_help。如果找到一个有效的,那么它将帮助消息写入一个临时文件,然后打开一个子进程,该进程使用临时文件的路径调用寻呼机。当寻呼机返回时,临时文件被删除。差不多就这些了。

非常欢迎您更新 get_pager 以添加您认为合适的寻呼程序。

调用脚本:

python3 hello.py --help ## Uses less
PAGER='nano --view' python3 hello.py --help ## Uses nano
PAGER=more python3 hello.py --help ## Uses more

【讨论】:

以上是关于Python:argparse 帮助文本的分页?的主要内容,如果未能解决你的问题,请参考以下文章

帮助文本中的 Python argparse 参数顺序

MySQL中的分页操作结合python

Python中的分页管理

Android中的分页文本

extjs 4.1.1 - 本地数据网格中的分页

QGraphicsTextItem的分页:将文本限制在特定的矩形区域