如何在Python 3创建与现有程序argparse子分析器?(How to create subp

2019-11-05 03:31发布

原帖:

如果一个人有一个可执行mini_program.py使用argparse结构如下:

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 ?)也有类似的用法以下:

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.pyparent_program.py

EDIT(具有错误消息的更具体的):

该程序

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

Answer 1:

父程序可能有这样的代码

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

作为书面,进口mini_program不运行它的解析器。 但是调用它的main的意志,但使用它在列表中查找sys.argv

家长应解析器的方式来写,它接受参数,它需要,并在输入不呛mini想,“-X”和“-y”。 然后,它会放在一个修改过的“额外”值sys.argv ,其中mini解析器可以处理。

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

nargs=argparse.REMAINDER , https://docs.python.org/3/library/argparse.html#nargs ,是收集剩余的参数用于使上的另一种方式。

如果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

从响应了“-h”帮助保持主分析器可能会非常棘手。 subparsers大概是这样做的最彻底的方法。

你可以用的的调用结合subparsers mini main 。 我不会尝试,现在上班了这些细节。

定义的另一种方法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定义解析器,但延缓解析。



Answer 2:

我实际的解决方案是一种适应以上:

# Controller
def main(argv=None):
    parser = argparse.ArgumentParser(prog="parent_program", add_help=True)
    parser.add_argument("subprogram")
    opts = parser.parse_args(argv)
    return opts.subprogram


# Initialize
if __name__ == "__main__":
    # Get the subprogram 
    subprogram = main([sys.argv[1]])
    module = importlib.import_module(subprogram)
    module.main(sys.argv[2:])


文章来源: How to create subparser with argparse from existing program in Python 3?