我正在尝试使用该cmd
模块在 Python 中构建一个小型交互式 shell。有没有一种简单的方法来允许多字命令?
例如,很容易处理hello
命令
class FooShell(Cmd):
def do_hello(self, args):
print("Hi")
但是,如果我想要更复杂的东西怎么办。假设我正在尝试实现一个 SQL shell 并想编写show tables
. 该show
命令可以采用多个目标,例如show track_counts
或show bonjour
。如果我想在 cmd 模块中处理这样的事情,看起来我必须编写以下内容:
class FooShell(Cmd):
def do_show(self, line):
args = line.strip().split(" ")
if args == []:
print("Error: show command requires arguments")
else:
if args[0] == "tables":
pass # logic here
elif args[0] == "bonjour":
pass # logic here
elif args[0] == "track_counts":
pass # logic here
else:
print("{} is not a valid target for the 'show' command".format(args[0]))
print("Valid targets are tables, bonjour, track_counts")
这种方法存在一些问题:
- 我必须自己编写错误消息。当我在 if 语句中添加其他命令时,我必须手动更新有效命令的列表。
- 用户键入后此处没有制表符补全
show
- 这真的很丑陋。
上面的另一种写法是这样的:
class FooShell(Cmd):
def do_show_tables(self, args):
pass
def do_show_bonjour(self, args):
pass
def do_show_track_counts(self, args):
pass
def do_show(self, line):
args = line.strip().split(" ")
if args == []:
print("Error: show command requires arguments")
else:
handlers = {
"tables": self.do_show_tables,
"bonjour": self.do_show_bonjour,
"track_counts": self.do_show_track_counts
}
handler = handlers.get(args[0], None)
if handler:
handler(args[1:])
else:
print("{} is not a valid target for the 'show' command".format(args[0]))
targets = ", ".join([key for key in handlers])
print("Valid targets are: {}".format(targets))
但这仍然不能在“显示”命令之后完成制表符。此外,现在感觉我基本上是在重写cmd
模块的核心功能。
有没有更简单的方法来做到这一点?我应该使用另一个模块而不是cmd
?
编辑:需要明确的是,我实际上并不是在编写 SQL shell,只是将其用作我希望如何解析多字命令的示例。