python argparse模块详解,如何在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:

Starting the program with a given command (each command has it's own

additional arguments) and additional arguments will run a specific

task.

Starting the program without a command will start a shell-like program that can take a line of arguments and process them as if the

program was called with the given line as it's arguments.

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

or with shell mode:

python program.py

cmd1 additional_args1

cmd2 additional_args2

quit

In addition, I also want my program to be able to take optional global arguments that will effect all commands.

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)

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.

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)

Restrictions:

I cannot use Python 3 (I know it can be easily done there)

Because of global optional arguments I cannot check to see if I get no arguments to skip arg parsing.

I don't want to add a new command to call shell, it must be when providing no command at all

So how can I achieve This kind of behavior with argparse and python 2.7?

解决方案

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)

sample runs:

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=, info='info'))

0901:~/mypy$ python stack46667843.py -i info cmd2 -o out

('cmd2', Namespace(cmd='cmd2', func=, info='info', output='out'))

0901:~/mypy$

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值