如何在 Python 2.7 中使用 Argparse 模块设置默认子解析器
我正在使用 Python 2.7 并且我正在尝试使用 argparse 完成类似 shell 的行为.我的问题是,总的来说,我似乎无法在 Python 2.7 中找到一种方法来使用 argparse 的子解析器作为可选.解释我的问题有点困难,所以我将描述我对程序的要求.
I'm using Python 2.7 and I'm trying to accomplish a shell like behavior using argparse. My issue, in general, that I cannot seem to find a way, in Python 2.7, to use argparse's subparsers as optional. It's kind of hard to explain my issue so I'll describe what I require from my program.
该程序有两种工作模式:
The program has 2 modes of work:
- 用给定的命令启动程序(每个命令都有自己的附加参数)和附加参数将运行特定的任务.
- 在没有命令的情况下启动程序将启动一个类似 shell 的程序,该程序可以接受一行参数并像处理它们一样处理它们使用给定的行作为参数调用程序.
因此,例如,如果我的程序支持cmd1"和cmd2"命令,我可以像这样使用它:
So, if for example my program supports 'cmd1' and 'cmd2' commands, I could use it like so:
python program.py cmd1 additional_args1
python program.py cmd2 additional_args2
或使用 shell 模式:
or with shell mode:
-
python 程序.py
cmd1 additional_args1
cmd2 additional_args2
退出
此外,我还希望我的程序能够采用将影响所有命令的可选全局参数.
In addition, I also want my program to be able to take optional global arguments that will effect all commands.
为此,我像这样使用 argparse(这是一个纯粹的例子):
For that I'm using argparse like so (This is a pure example):
parser = argparse.ArgumentParser(description="{} - Version {}".format(PROGRAM_NAME, PROGRAM_VERSION)) parser.add_argument("-i", "--info", help="Display more information") subparsers = parser.add_subparsers() parserCmd1 = subparsers.add_parser("cmd1", help="First Command") parserCmd1.set_defaults(func=cmd1) parserCmd2 = subparsers.add_parser("cmd2", help="Second Command") parserCmd2.add_argument("-o", "--output", help="Redirect Output") parserCmd2.set_defaults(func=cmd2)
所以我可以调用 cmd1(没有额外的参数)或 cmd2(有或没有 -o 标志).对于两者,我都可以添加标志 -i 以显示被调用命令的更多信息.
So I can call cmd1 (with no additional args) or cmd2 (with or without -o flag). And for both I can add flag -i to display even more information of the called command.
我的问题是我无法激活 shell 模式,因为我必须提供 cmd1 或 cmd2 作为参数(因为使用了强制的子解析器)
My issue is that I cannot activate shell mode, because I have to provide cmd1 or cmd2 as an argument (because of using subparsers which are mandatory)
限制:
- 我不会使用 Python 3(我知道在那里可以轻松完成)
- 由于全局可选参数,我无法检查是否没有参数跳过 arg 解析.
- 我不想添加一个新的命令来调用 shell,它必须是在根本不提供任何命令的情况下
那么如何使用 argparse 和 python 2.7 实现这种行为?
So how can I achieve This kind of behavior with argparse and python 2.7?
另一个想法是使用 2 阶段解析.一个处理全局变量",返回它无法处理的字符串.然后有条件地使用子解析器处理额外的内容.
Another idea is to use a 2 stage parsing. One handles 'globals', returning strings it can't handle. Then conditionally handle the extras with subparsers.
import argparse
def cmd1(args):
print('cmd1', args)
def cmd2(args):
print('cmd2', args)
parser1 = argparse.ArgumentParser()
parser1.add_argument("-i", "--info", help="Display more information")
parser2 = argparse.ArgumentParser()
subparsers = parser2.add_subparsers(dest='cmd')
parserCmd1 = subparsers.add_parser("cmd1", help="First Command")
parserCmd1.set_defaults(func=cmd1)
parserCmd2 = subparsers.add_parser("cmd2", help="Second Command")
parserCmd2.add_argument("-o", "--output", help="Redirect Output")
parserCmd2.set_defaults(func=cmd2)
args, extras = parser1.parse_known_args()
if len(extras)>0 and extras[0] in ['cmd1','cmd2']:
args = parser2.parse_args(extras, namespace=args)
args.func(args)
else:
print('doing system with', args, extras)
样本运行:
0901:~/mypy$ python stack46667843.py -i info
('doing system with', Namespace(info='info'), [])
0901:~/mypy$ python stack46667843.py -i info extras for sys
('doing system with', Namespace(info='info'), ['extras', 'for', 'sys'])
0901:~/mypy$ python stack46667843.py -i info cmd1
('cmd1', Namespace(cmd='cmd1', func=<function cmd1 at 0xb74b025c>, info='info'))
0901:~/mypy$ python stack46667843.py -i info cmd2 -o out
('cmd2', Namespace(cmd='cmd2', func=<function cmd2 at 0xb719ebc4>, info='info', output='out'))
0901:~/mypy$