繁体   English   中英

动态 cmd.Cmd 制表符补全

[英]dynamic cmd.Cmd tab-completion

我尝试使用Cmd ,但不是单独添加所有函数/命令,而是希望它从字典中读取函数名并动态添加它们。 preloop应该添加函数do_aacomplete_aado_bbcomplete_bb 命令取自字典,并使用setattr添加

import cmd

class C(cmd.Cmd):

    commands = {'aa': ['aa1', 'aa2'],
                'bb': ['bb1', 'bb2']}

    def preloop(self):
        for k, v in self.commands.items():
            self.k = k
            setattr(C, 'do_' + k, k)
            setattr(C, 'complete_' + k, self.complete_)

    def complete_(self, text, line, start_index, end_index):
        if text:
            return [
                command for command in self.commands[self.k]
                if command.startswith(text)
            ]
        else:
            return self.commands[self.k]


if __name__ == '__main__':
    C().cmdloop()

问题是自动完成实际上并没有得到正确的二级命令:

(Cmd) aa 
bb1  bb2  # should be aa1 aa2
(Cmd) bb
bb1  bb2 

为什么会发生这种情况,如何解决?

您的脚本不适用于Python 3.8.10可能是因为这一行

setattr(C, 'do_' + k, k)

k不是一种方法。 顺便说一句,错误在这一行:

for k, v in self.commands.items():
     self.k = k  # <--

您不断地重新分配self.k直到commands字典的最后一个键,即bb 稍后, complete_方法总是被评估为self.commands['bb'] 这是一个可能的工作版本:

import cmd

class C(cmd.Cmd):

    commands = {
            'aa': ['aa1', 'aa2'],
            'bb': ['bb1', 'bb2']
        }
        
    def monad_print(self, *args):
        print(args)

    def preloop(self):
        for k, v in self.commands.items():
            setattr(C, 'do_' + k, lambda self, arg, k=k: self.monad_print(k, arg))
            setattr(C, 'complete_' + k, self.complete_)

    def complete_(self, text, line, start_index, end_index):
        command = line.split(' ', maxsplit=1)[0]
        if text:
            return [
                command for command in self.commands[command]
                if command.startswith(text)
            ]
        else:
            return self.commands[command]


if __name__ == '__main__':
    C().cmdloop()

唯一的区别是命令现在取自整个读取行,特别是str.split()的第一个标记。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM