自动注册";“命令”;用于python中的命令行程序

自动注册";“命令”;用于python中的命令行程序,python,command-line-tool,Python,Command Line Tool,我想开发一个命令行程序,可以处理并为子命令提供“帮助”。具体来说,假设我有一个名为“cgent”的脚本,我希望让子命令“abc”、“def”和“xyz”执行并接受sys.args的其余部分,以便由optparse进行处理 cgent abc [options] cgent help abc .... cgent abc[选项] cgent帮助abc .... 如果我硬编码子命令名称,所有这些都很简单。但是,我希望能够通过添加类或模块(?)继续添加子命令。例如,这类似于web框架用于添加控制器的

我想开发一个命令行程序,可以处理并为子命令提供“帮助”。具体来说,假设我有一个名为“cgent”的脚本,我希望让子命令“abc”、“def”和“xyz”执行并接受sys.args的其余部分,以便由optparse进行处理

cgent abc [options] cgent help abc .... cgent abc[选项] cgent帮助abc .... 如果我硬编码子命令名称,所有这些都很简单。但是,我希望能够通过添加类或模块(?)继续添加子命令。例如,这类似于web框架用于添加控制器的想法。我曾试图挖掘塔架,看看是否可以重现那里的情况,但我还没有解开其中的逻辑。有什么建议吗

谢谢, 肖恩

你必须创建一个“命令注册表”。这可以像字典一样简单

在主程序中,您可以执行以下操作:

commands = {}
在您添加的任何子模块中

from yourmodule.main import commands

def mynewcommand(arguments=here):
    pass

commands['newcommand'] = mynewcommand

然后可以使用argparse来处理这些命令。在这种情况下,您的模块也需要为命令添加子parser部分。

如果您不必对参数进行复杂的解析,我建议使用该模块。它允许您通过decorator定义子命令及其参数。例如:

#!/usr/bin/env python
import baker

@baker.command()
def foo(a=1):
    print 'foo:', a

@baker.command()
def baz(b=1):
    print 'baz:', b

baker.run()
使用(可选)参数
a
b
定义两个子命令
foo
baz
。 所以你可以这样使用它们:

$ ./test_baker.py foo --a 2
foo: 2
$ ./test_baker.py baz
baz: 1
它还使用docstring生成帮助

由于
baker
模块是全局的,因此子命令可以跨越多个
.py
文件。只要导入子命令,子命令就会自动注册

此外,它只是一个
.py
文件,因此您可以将其放到源代码树中