繁体   English   中英

python cmd.Cmd 动态添加命令

[英]python cmd.Cmd dynamically add a command

我正在尝试构建一个 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:我认为您必须使用 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因此会产生误导和混淆。

对我来说,当我用相等运算符设置它时它就起作用了。 它确实作为一个有效的命令工作。

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

我找到了一种解决方法,使其适用于自动完成和帮助。 重新实现get_names()在你的类(我不知道为什么他们用自己一流的,而不是自我存在)

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

暂无
暂无

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

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