2015-06-26 53 views
3

基本预期用途:如何有条件地让蟒蛇的argparse模块需要额外的参数

my_framework create Project_title /path/to/project

OR

my_framework create Project_title(即用当前的工作目录)

OR

my_framework update (即更新my_framework而不是创建新项目)

我知道我可以做name可选向其提供一个默认的,但是,在现实中name提供可选用户输入create作为第一个参数。

我想出的最佳解决方案是使用name的默认值,然后如果参数name等于其默认值,则会抛出错误。但是,如果有一种方法可以为我做这个工作,我宁愿学会这样做。

写两个脚本,my_framework_createmy_framework_update并不吸引我审美。

#!/usr/bin/env python 


import argparse 
import os 
import shutil 
from subprocess import call 

template_path = "/usr/local/klibs/template" 
parser = argparse.ArgumentParser("MY_FRAMEWORK CLI", description='Creates a new MY_FRAMEWORK project or updates MY_FRAMEWORK') 
parser.add_argument('action', choices=['create', 'update'], type=str, help='<help text>') 
parser.add_argument('name', type=str, help='<help text>') 
parser.add_argument('path', default=os.getcwd(), nargs="?", type=str, help='<help text>') 
args = parser.parse_args() 

if args.action == "create": 
    # do the create stuff 

if args.action == "update": 
    # do the update stuff 
+0

你想用subparsers此:https://docs.python.org/2/library/argparse.html#argparse.ArgumentParser.add_subparsers – Wolph

+0

我不完全理解题。为什么使用update调用my_framework时不需要名称?它不应该总是需要一个名字,以防用户有两个框架吗? –

+0

对不起; 'update'适用于'MY_FRAMEWORK'而不是用它创建的项目(即它基本上检查github上的新版本,如果找到了它,则将其拉出)。 – Jonline

回答

4

做到这一点,最好的办法是用subparser

从文档的一个例子:

>>> parser = argparse.ArgumentParser() 
>>> subparsers = parser.add_subparsers(title='subcommands', 
...         description='valid subcommands', 
...         help='additional help') 
>>> subparsers.add_parser('foo') 
>>> subparsers.add_parser('bar') 
>>> parser.parse_args(['-h']) 
usage: [-h] {foo,bar} ... 

optional arguments: 
    -h, --help show this help message and exit 

subcommands: 
    valid subcommands 

    {foo,bar} additional help 

你的情况,你会createupdate作为单独subparsers。

例子:

def create(args): 
    # do the create stuff 
    print(args) 


def update(args): 
    # do the update stuff 
    print(args) 


parser = argparse.ArgumentParser() 
subparsers = parser.add_subparsers(title='subcommands', 
            description='valid subcommands', 
            help='additional help') 

create_parser = subparsers.add_parser('create') 
create_parser.add_argument('name', type=str) 
create_parser.set_defaults(func=create) 

update_parser = subparsers.add_parser('update') 
update_parser.set_defaults(func=update) 
+0

优雅。当'create'是第一个参数时,这会要求subparser的参数,而在进入'update'时忽略其他参数? – Jonline

+1

@Jonline:是的,它会:)当进入'update'时,它会进入第二个分析器,使用'create'将会进入第一个分析器。这应该做你正在寻找一个干净的方式:) – Wolph

+0

是的,我现在有这个运行,迷人的解决方案。你的代码中有两个小的语法错误(试图编辑但是<6个字符):'update_parser subparsers.add_parser('update')'needs'='并且'setdefaults'都应该是蛇情况。 – Jonline