如何构建一个具有独立命令模块的Python命令行应用程序
我正在用cmd2模块写一个Python命令行工具,这个模块是cmd的升级版。这个工具是一个管理应用程序,用来管理多个子模块。
我想把代码结构设计成每个子模块都有自己的类,负责提供可以在该模块上执行的命令。但我不太确定该怎么组织这些代码,因为命令类的工作方式让我有些困惑。
所以我想要的结构大概是这样的:
import cmd
class ConsoleApp(cmd.Cmd):
# this is the main app and should get the commands from the sub-modules
app = ConsoleApp()
app.cmdloop()
然后这些子模块会被单独定义。
class SubModuleA():
def do_sm_a_command_1(self, line):
print "sm a command 1"
class SubModuleB():
def do_sm_b_command_1(self, line):
print "sm b command 2"
我该如何组织这些代码,让主应用能够获取子模块中的命令呢?
谢谢,Jon
1 个回答
1
你可以尝试把你的子模块(SubModules)设计成主控制台应用(ConsoleApp)的插件。这样的话,你需要在控制台应用里添加几个新方法。比如,可以有一个叫 add_command_module(self, klass)
的方法,这个方法的作用就是把子模块(比如 SubModuleA)添加到控制台应用内部的一个列表里。
接着,在控制台应用中,你需要重写 onecmd
这个方法,让它看起来像下面这样:
def onecmd(self, line):
if not line:
return self.emptyline()
if cmd is None:
return self.default(line)
self.lastcmd = line
if cmd == '':
return self.default(line)
else:
# iterate over all submodules that have been added including ourselves
# self.submodules would just be a list or set of all submodules as mentioned above
func = None
for submod in self.submodules:
# just return the first match we find
if hasattr(submod, 'do_%s' % cmd):
func = getattr(submod, 'do_%s' % cmd)
break # instead of breaking, you could also add up all the modules that have
# this method, and tell the user to be more specific
if func is not None:
return func(arg)
else:
return self.default(line)
你还可以对 parseline
方法进行一些修改,让它能够识别命令的子模块前缀等等……