我正在尝试构建一个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()
答案 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
的任何知识,因此会产生误导和混淆。