Python readline,使用Cmd界面循环制表符
我在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()
按两次标签将显示可能性。 再次按下标签也是一样的。
我的问题是,如何获得在第三个标签页上循环的选项? 在readline术语中,我认为这叫做Tab: menu-complete
,但是我看不到如何将它应用到Cmd
实例。
我已经尝试过了:
readline.parse_and_bind('Tab: menu-complete')
实例化解析器实例之前和之后。 没有运气。
我也尝试将"Tab: menu-complete"
传递给Cmd
构造函数。 这里也没有运气。
任何人都知道它是如何完成的?
干杯!
最简单的技巧是在menu-complete
后添加一个空格:
parser = CommandParser(completekey="tab: menu-complete ")
所执行的绑定表达式
readline.parse_and_bind(self.completekey+": complete")
将成为
readline.parse_and_bind("tab: menu-complete : complete")
第二个空间之后的所有内容都会被忽略,因此它与tab: menu-complete
。
如果你不想依赖readline解析的行为(我没有看到它被记录),你可以使用str
一个子类拒绝扩展为completekey:
class stubborn_str(str):
def __add__(self, other):
return self
parser = CommandParser(completekey=stubborn_str("tab: menu-complete"))
self.completekey+": complete"
现在与self.completekey
相同。
不幸的是,似乎唯一的解决办法cmdloop
从cmd.Cmd
类中将cmd.Cmd
方法cmdloop
为猴子,或者自行cmd.Cmd
。
正确的方法是使用"Tab: menu-complete"
,但是它被类重写,如第115行所示: readline.parse_and_bind(self.completekey+": complete")
,它永远不会被激活。 (对于第115行和整个cmd
包,请参阅:https://hg.python.org/cpython/file/2.7/Lib/cmd.py)。 我已经在下面显示了该功能的编辑版本,以及如何使用它:
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('rn')
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
一旦你对类方法进行了猴子补丁(或实现了你自己的类),它提供了正确的行为(尽管没有突出显示和反向标签,但是这些可以在必要时用其他键实现)。
链接地址: http://www.djcxy.com/p/56427.html上一篇: Python readline, tab completion cycling with the Cmd interface
下一篇: api python library : raise AttributeError(“No constructor defined”)