如何从Python 3中的现有程序使用argparse创建子解析器? [英] How to create subparser with argparse from existing program in Python 3?

查看:161
本文介绍了如何从Python 3中的现有程序使用argparse创建子解析器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果具有使用argparse的可执行文件mini_program.py具有以下结构:

If one has an executable mini_program.py that uses argparse with the following structure:

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-X', '--attribute_matrix', type=str, help = 'Input: Path/to/Tab-separated-value.tsv')
    parser.add_argument('-y', '--target_vector', type=str, help = 'Input: Path/to/Tab-separated-value.tsv')
    opts = parser.parse_args()

if __name__ == "__main__":
    main()

如何创建一个控制器程序parent_program.py,该程序使用argparse(我认为是subparser?)具有与以下类似的用法:

How can one create a controller program parent_program.py that uses argparse (I think with subparser?) to have a similar usage to below:

python parent_program.py --help

blah-blah list of programs that can be used

然后使用子程序:

python parent_program.py mini_program --help

-X description
-y description
etc...

所有参数如何从mini_program.py传播到parent_program.py?

How could all of the parameters propagate up from mini_program.py to the parent_program.py?

import argparse
def main():
    parser = argparse.ArgumentParser()
    # Subprograms
    subprograms = parser.add_subparsers(title="subprograms")
    # ============
    # mini-program
    # ============
    parser_miniprogram = subprograms.add_parser("miniprogram")

    # Input
    parser_miniprogram.add_argument('-X', '--attribute_matrix', type=str, help = 'Input: Path/to/Tab-separated-value.tsv')
    parser_miniprogram.add_argument('-y', '--target_vector', type=str, help = 'Input: Path/to/Tab-separated-value.tsv')
    opts = parser.parse_args()
    opts_miniprogram = parser_miniprogram.parse_args()
    print(opts_miniprogram.__dict__)

if __name__ == "__main__":
    main()

检查以确保文档正常工作

# parent program
python parent_program.py --help
usage: parent_program.py [-h] {miniprogram} ...

optional arguments:
  -h, --help     show this help message and exit

subprograms:
  {miniprogram}

# miniprogram
python parent_program.py miniprogram --help
usage: parent_program.py miniprogram [-h] [-X ATTRIBUTE_MATRIX]
                                     [-y TARGET_VECTOR]

optional arguments:
  -h, --help            show this help message and exit
  -X ATTRIBUTE_MATRIX, --attribute_matrix ATTRIBUTE_MATRIX
                        Input: Path/to/Tab-separated-value.tsv
  -y TARGET_VECTOR, --target_vector TARGET_VECTOR
                        Input: Path/to/Tab-separated-value.tsv

尝试运行它:

python parent_program.py miniprogram -X ../../Data/X_iris.noise_100.tsv.gz -y ../../Data/y_iris.tsv
usage: parent_program.py miniprogram [-h] [-X ATTRIBUTE_MATRIX]
                                     [-y TARGET_VECTOR]
parent_program.py miniprogram: error: unrecognized arguments: miniprogram

推荐答案

父程序可能具有类似

import mini_program
import sys
<do its own parsing>
if 'use_mini':
    <modify sys.argv>
    mini_program.main()

如前所述,导入mini_program不会运行其解析器.但是调用它的main会,但是会使用它在sys.argv中找到的列表.

As written, importing mini_program doesn't run its parser. But calling its main will, but using the list it finds in sys.argv.

父解析器的编写方式应使其接受所需的参数,并且不会阻塞mini所需的输入-X和-y.然后,将这些额外"值放入经过修改的sys.argv中,由mini解析器可以处理.

The parent parser should be written in a way that it accepts arguments that it needs, and doesn't choke on inputs the mini wants, '-X' and '-y'. It would then puts those 'extra' values in a modified sys.argv, which the mini parser can handle.

parse_known_args是接受未知参数的一种方法, https://docs.python.org/3/library/argparse. html#partial-parsing

parse_known_args is one way of accepting unknown arguments, https://docs.python.org/3/library/argparse.html#partial-parsing

nargs=argparse.REMAINDER https://docs.python.org/3/library/argparse.html#nargs 是另一种收集剩余参数以进行传递的方法.

nargs=argparse.REMAINDER, https://docs.python.org/3/library/argparse.html#nargs, is another way of collecting remaining arguments for passing on.

mini main的写法是:

def main(argv=None):
    parser = argparse.ArgumentParser()
    parser.add_argument('-X', '--attribute_matrix', type=str, help = 'Input: Path/to/Tab-separated-value.tsv')
    parser.add_argument('-y', '--target_vector', type=str, help = 'Input: Path/to/Tab-separated-value.tsv')
    opts = parser.parse_args(argv)

可以用

mini_program.main(['-X', 'astring','-y','another'])

,即具有明确的argv列表,而不是通过sys.argv进行工作.

that is, with an explicit argv list, instead of working through sys.argv.

使主解析器不响应"-h"帮助可能很棘手. subparsers可能是最干净的方法.

Keeping the main parser from responding to a '-h' help could be tricky. subparsers is probably the cleanest way of doing that.

您可以将子解析器与mini main的调用结合使用.我现在不会尝试得出这些细节.

You could combine subparsers with the invocation of a the mini main. I won't try to work out those details now.

定义main的另一种方法是:

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-X', '--attribute_matrix', type=str, help = 'Input: Path/to/Tab-separated-value.tsv')
    parser.add_argument('-y', '--target_vector', type=str, help = 'Input: Path/to/Tab-separated-value.tsv')
    return parser

并将其用作

 opts = main().parse_args()
 opts = mini_program.main().parse_args()

换句话说,使用main定义解析器,但是延迟解析.

in other words, use main to define the parser, but delay the parsing.

这篇关于如何从Python 3中的现有程序使用argparse创建子解析器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆