Python readline,使用Cmd接口循环制表符

Python readline,使用Cmd接口循环制表符,python,readline,Python,Readline,我正在使用Python中的cmd.cmd类为我的程序提供一个简单的readline接口 独立示例: from cmd import Cmd class CommandParser(Cmd): def do_x(self, line): pass def do_xy(self, line): pass def do_xyz(self, line): pass if __name__ == "__main__":

我正在使用Python中的
cmd.cmd
类为我的程序提供一个简单的readline接口

独立示例:

from cmd import Cmd

class CommandParser(Cmd):

    def do_x(self, line):
        pass

    def do_xy(self, line):
        pass

    def do_xyz(self, line):
        pass

if __name__ == "__main__":
    parser = CommandParser()
    parser.cmdloop()
按tab键两次将显示可能性。再次按tab键也会执行相同的操作

我的问题是,如何获得在第三次按tab键时循环的选项?在readline中,我认为这叫做
Tab:menu complete
,但我不知道如何将其应用于
Cmd
实例

我已经试过了:

readline.parse_and_bind('Tab: menu-complete')
在实例化解析器实例之前和之后。不走运

我还尝试将
“Tab:menu complete”
传递给
Cmd
构造函数。这里也不走运

有人知道是怎么做的吗


干杯

不幸的是,似乎唯一的解决办法是从
cmd.cmd
类中对方法
cmdloop
进行猴子补丁,或者自己使用

正确的方法是使用
“Tab:menu complete”
,但它被第115行所示的类覆盖:
readline.parse_和_bind(self.completekey+“:complete”)
,它永远不会被激活。(对于第115行和整个
cmd
包,请参见以下内容:)。我在下面展示了该函数的编辑版本,以及如何使用它:

import cmd


# note: taken from Python's library: https://hg.python.org/cpython/file/2.7/Lib/cmd.py
def cmdloop(self, intro=None):
    """Repeatedly issue a prompt, accept input, parse an initial prefix
    off the received input, and dispatch to action methods, passing them
    the remainder of the line as argument.
    """

    self.preloop()
    if self.use_rawinput and self.completekey:
        try:
            import readline
            self.old_completer = readline.get_completer()
            readline.set_completer(self.complete)
            readline.parse_and_bind(self.completekey+": menu-complete")  # <---
        except ImportError:
            pass
    try:
        if intro is not None:
            self.intro = intro
        if self.intro:
            self.stdout.write(str(self.intro)+"\n")
        stop = None
        while not stop:
            if self.cmdqueue:
                line = self.cmdqueue.pop(0)
            else:
                if self.use_rawinput:
                    try:
                        line = raw_input(self.prompt)
                    except EOFError:
                        line = 'EOF'
                else:
                    self.stdout.write(self.prompt)
                    self.stdout.flush()
                    line = self.stdin.readline()
                    if not len(line):
                        line = 'EOF'
                    else:
                        line = line.rstrip('\r\n')
            line = self.precmd(line)
            stop = self.onecmd(line)
            stop = self.postcmd(stop, line)
        self.postloop()
    finally:
        if self.use_rawinput and self.completekey:
            try:
                import readline
                readline.set_completer(self.old_completer)
            except ImportError:
                pass

# monkey-patch - make sure this is done before any sort of inheritance is used!
cmd.Cmd.cmdloop = cmdloop

# inheritance of the class with the active monkey-patched `cmdloop`
class MyCmd(cmd.Cmd):
    pass
import cmd
#注意:摘自Python库:https://hg.python.org/cpython/file/2.7/Lib/cmd.py
def cmdloop(自我,介绍=无):
“”“重复发出提示、接受输入、分析初始前缀
关闭接收到的输入,并分派给操作方法,传递它们
行的其余部分作为参数。
"""
self.preloop()
如果self.use_rawinput和self.completekey:
尝试:
导入读线
self.old\u completer=readline.get\u completer()
readline.set\u完成符(self.complete)

readline.parse_和_bind(self.completekey+“:menu complete”)#最简单的技巧是在
menu complete
之后添加一个空格:

parser = CommandParser(completekey="tab: menu-complete ")
执行的绑定表达式

readline.parse_and_bind(self.completekey+": complete")
然后会变成

readline.parse_and_bind("tab: menu-complete : complete")
第二个空格后的所有内容都会被忽略,因此它与
选项卡:menu complete
相同

如果您不想依赖readline解析的行为(我没有看到它的文档),可以使用拒绝扩展为completekey的
str
子类:

class stubborn_str(str):
    def __add__(self, other):
        return self

parser = CommandParser(completekey=stubborn_str("tab: menu-complete"))

self.completekey+”:complete“
现在与
self.completekey

相同,似乎有一种方法
Cmd.complete
可以覆盖,但不要问我如何…这个库看起来不像你想要的,你能直接使用readline吗?谢谢。它使我能够自动完成一些数据,而这些数据在其他方法中是很困难的,比如补全中的空格。