如何使用 Python 3 中现有程序的 argparse 创建子解析器?
How to create subparser with argparse from existing program in Python 3?
原文post:
如果一个可执行文件 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()
如何创建一个使用 argparse
(我认为是 subparser
?)的控制器程序 parent_program.py
以具有与以下类似的用法:
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”。然后它将那些 'extra' 值放入修改后的 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
可能是最简洁的方法。
您可以将子解析器与 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:])
原文post:
如果一个可执行文件 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()
如何创建一个使用 argparse
(我认为是 subparser
?)的控制器程序 parent_program.py
以具有与以下类似的用法:
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”。然后它将那些 'extra' 值放入修改后的 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
可能是最简洁的方法。
您可以将子解析器与 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:])