2

我正在尝试使用该cmd模块在 Python 中构建一个小型交互式 shell。有没有一种简单的方法来允许多字命令?

例如,很容易处理hello命令

class FooShell(Cmd):
    def do_hello(self, args):
        print("Hi")

但是,如果我想要更复杂的东西怎么办。假设我正在尝试实现一个 SQL shell 并想编写show tables. 该show命令可以采用多个目标,例如show track_countsshow 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,只是将其用作我希望如何解析多字命令的示例。

4

0 回答 0