簡體   English   中英

如何從Python 3中的現有程序使用argparse創建子解析器?

[英]How to create subparser with argparse from existing program in Python 3?

原始帖子:

如果有一個可執行文件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.py傳播到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找到的列表。

父解析器的編寫方式應使其接受所需的參數,並且不要阻塞mini想要的輸入“ -X”和“ -y”。 然后,將這些“額外”值放入經過修改的sys.argvmini解析器可以處理。

parse_known_args是接受未知參數的一種方法, https: parse_known_args

nargs=argparse.REMAINDERhttps: nargs=argparse.REMAINDER ,是另一種收集剩余參數以進行傳遞的方法。

如果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可能是最干凈的方法。

您可以將子解析器與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來定義解析器,但是會延遲解析。

我的實際解決方案是對以上內容的適應:

# 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:])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM