python cmd.Cmd动态添加命令

时间:2015-08-09 01:20:01

标签: python cmd

我正在尝试构建一个cli框架,其中需要动态添加命令。我想要实现的是 - 我将有一个从cmd.Cmd继承的最小类,稍后我将在单独的类中编写我的命令并将这些命令与主类一起加载。

以下是我尝试过但在尝试执行showmore命令时,它会抛出TypeError

import cmd

class MyExtraCmds(cmd.Cmd):

  def do_showmore(self, *args):
    print (type(self))
    print ("Show more command")

class MyCmd(cmd.Cmd):

  def __init__(self, target=None, user=None, passwd=None):
    cmd.Cmd.__init__(self)

  def do_show(self, *args):
    print (type(self))
    print ("Show command")

  def do_EOF(self, line):
    return True

if __name__ == "__main__":
    setattr(  MyCmd, 'do_showmore', MyExtraCmds.do_showmore)
    print (dir(MyCmd))
    target = MyCmd()
    target.cmdloop()

2 个答案:

答案 0 :(得分:1)

对我来说,当我用相等运算符设置它时,它就可以工作。它确实是有效命令。

p = MyCmd()
p.do_extra = extra_command
p.cmdloop()

,我找到了一种解决方法,使其可以自动完成并获得帮助。 在您的课程中重新实现get_names()(我不知道他们为什么使用self。 class 而不是self)

class MyCmd(cmd.Cmd):
  def get_names(self):
    return dir(self)

答案 1 :(得分:0)

编辑2:我认为你必须使用Python 2,因为在Python 3中,这只是有用......

MyExtrasCommand是一个不同的类,所以这不起作用,因为对于普通的InstanceMethod,第一个参数必须是该类的实例。

但Python类打开;您可以稍后添加。最简单的方法是从当前不在类中的方法开始,然后在运行时将它们正确地添加到类中。例如,这将正常工作:

import cmd

def do_showmore(self, *args):
    print (type(self))
    print ("Show more command")

class MyCmd(cmd.Cmd):

    def __init__(self, target=None, user=None, passwd=None):
        cmd.Cmd.__init__(self)

    def do_show(self, *args):
        print (type(self))
        print ("Show command")

    def do_EOF(self, line):
        return True

if __name__ == "__main__":
    setattr(  MyCmd, 'do_showmore', do_showmore)
    print (dir(MyCmd))
    target = MyCmd()
    target.cmdloop()

如果您打印MyCmd.do_showmore的类型,您将看到您的函数已正确包装到InstanceMethod中。

编辑(仅供参考 - 您可能并非想要这样做...)

由于Python中的所有内容都是开放且可检查的,因此可以通过更改单行来使您的初始方法工作。以下内容适用于Python 2.7:

setattr(  MyCmd, 'do_showmore', MyExtraCmds.do_showmore.im_func)

对于Python 2.7,将.im_func添加到此行的末尾说“从MyExtraCmds.do_showmore未绑定方法中获取基础函数并使用它”。我之所以提到这一点,是因为有时候有充分的理由像这样使用深色伏都教。但是你所描述的用例似乎不适合这里,例如,如果你向MyExtraCmds添加了额外的类变量并且期望do_showmore能够使用MyExtraCmds,那么它可能会非常混乱。访问他们。您从MyCmd中删除并添加到MyExtraCmds的功能将不再具有asyncio的任何知识,因此会产生误导和混淆。