Python argparse:位置参数的单个选择的使用情况报告?

Python argparse:位置参数的单个选择的使用情况报告?,python,argparse,Python,Argparse,我正在尝试重构一个程序,以使用新的标准argparse模块。根据下面的结构,我应该使用主位置参数,还是其他方法 foo [OPTION]... COMMAND [PACKAGE(S)]... Commands: available - show packages available to be installed install - download and install packages, including dependencies remove -

我正在尝试重构一个程序,以使用新的标准argparse模块。根据下面的结构,我应该使用主位置参数,还是其他方法

foo [OPTION]... COMMAND [PACKAGE(S)]...

Commands:
    available -  show packages available to be installed
    install   -  download and install packages, including dependencies
    remove    -  uninstall packages
    ...snip
    version   -  display installed version of package

Options:
    -d,--download          download only
    -i,--ini=FILE          use alternate setup.ini
    ...snip
选项示例,简洁明了,但没有每个命令的使用帮助:

parser = argparse.ArgumentParser()
commands = "available install remove ... version".split()
parser.add_argument('command', choices=commands, 
    help="generic help for all 12 commands goes here")
选项在逻辑上更符合程序,因为命令行上的命令后面的内容对于所有选项基本相同。虽然子命令似乎希望我将每个命令视为其自身的世界,并且涉及代码的3倍。然而,似乎没有一种方法可以显示选项中每个选项的用法(?)也许有第三条路线我没有看到

我使用的是python 2.7。

我会选择这个选项

您不必编写更多的代码:在
Main
cli类中构建命令类,每个类都带有自己的设置(需要时使用继承),实例化主解析器,然后将其交给需要添加/设置自己的命令

答案很简短,但如果不清楚,请告诉我,我将添加一个代码示例


粗略的例子 您应该将命令构建为类:

class Install(BaseCommand):

    help = "download and install packages"

    @classmethod
    def interface(cls, cmd_parser):
        cmd_parser.add_argument('--foo')
        cmd_parser.set_defaults(cmd=cls)    # this line is very important

    def start(self, foo=None):
        # command execution
您的命令行界面也应该是一个类:

class Main(BaseCli):

    def __init__(self):
        self.commands = [Install]   # just the command classes

        self._parser = argparse.ArgumentParser()
        self._subparsers = self._parser.add_subparsers()

    def load_interface(self):
        for cmd in self.commands:
            cmd_parser = self.add_command_parser(help=cmd.help)
            cmd.interface(cmd_parser)

    def add_command_parser(self, *args, **kwargs):
        return self._subparsers.add_parser(*args, **kwargs)

    def parse_args(self, args=None, namespace=None):
        return self._parser.parse_args(args, namespace)

    def start_session(self, namespace):
        # this will instantiate the appropriate command class
        cmd = namespace.cmd()
        # and call its start method with the user args
        cmd.start(**namespace.__dict__)
要像这样使用:

cli = Main()
cli.load_interface()
args = cli.parse_args()
cli.start_session(args)

请注意,使用这种方法,您将拥有所有的继承权!:)

也许这就是我一直以来使用子命令的方式?在对每个选项做出反应之前,我已经为每个选项准备了两行代码,请参见
def subs()
@mattwillkie:如果您能给出+1(这意味着您觉得这个答案至少很有用),因为您要求我检查您的代码。(但我还是要看一下…@Mattwillkie:你可以把函数和swith放到类中,这样维护和实现起来就更容易了,我添加了一个代码示例。非常感谢Rik。我没有对最初的答案投赞成票,因为在这种情况下,我无法判断它是否有用。我刚刚开始理解和使用类(而不是继承),不知道如何开始实现这个建议。现在我有东西要嚼了!再次感谢你。