Python argparse:位置参数的单个选择的使用情况报告?
我正在尝试重构一个程序,以使用新的标准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 -
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。我没有对最初的答案投赞成票,因为在这种情况下,我无法判断它是否有用。我刚刚开始理解和使用类(而不是继承),不知道如何开始实现这个建议。现在我有东西要嚼了!再次感谢你。