检查通过python cmd模块传递的参数

检查通过python cmd模块传递的参数,python,python-2.7,autocomplete,cmd,Python,Python 2.7,Autocomplete,Cmd,这是一个由两部分组成的问题,请参见以下内容: 我需要创建一些控制台,供测试人员手动运行一些命令使用cmd模块是否是一种好方法? 以下是迄今为止我使用cmd模块获得的代码,我只是想学习,目前我有两个问题: 为什么自动完成功能不起作用?如果我双击,我什么也得不到,光标只会向前移动。自动完成功能不是默认提供的吗 我必须为每个方法处理错误数量的参数吗?我想方法-‘帮助’文本自动显示,如果方法调用的参数数量错误,或当他们应该调用的参数,他们没有 class InteractiveConsole(

这是一个由两部分组成的问题,请参见以下内容:

  • 我需要创建一些控制台,供测试人员手动运行一些命令使用
    cmd
    模块是否是一种好方法?
以下是迄今为止我使用
cmd
模块获得的代码,我只是想学习,目前我有两个问题:

  • 为什么自动完成功能不起作用?如果我双击
    ,我什么也得不到,光标只会向前移动。自动完成功能不是默认提供的吗

  • 我必须为每个方法处理错误数量的参数吗?我想方法-‘帮助’文本自动显示,如果方法调用的参数数量错误,或当他们应该调用的参数,他们没有

class InteractiveConsole(cmd.cmd):
“”“交互式命令行”“”
定义初始化(自):
cmd.cmd.\uuuu init\uuuuu(自)
self.prompt=“=>>”
self.intro=“欢迎使用IRT控制台!”
def do_历史(自身,参数):
“”“打印已输入命令的列表”“”
打印自我
def do_退出(自身,参数):
“”“从控制台退出”“”
返回-1
def do_帮助(自我,参数):
“”“获取有关命令的帮助
不带参数的“help”或“?”打印可获得帮助的命令列表
“帮助”或“帮助”?“帮助
"""
##定义此方法的唯一原因是用于文档字符串中的帮助文本
cmd.cmd.do_help(self,args)
##覆盖Cmd对象中的方法##
def预循环(自):
“”“在提示用户输入命令之前初始化。
尽管Cmd文档中有声明,Cmd.preloop()不是存根。
"""
cmd.cmd.preloop(self)##设置命令完成
self._hist=[]##还没有历史记录
self._locals={}##初始化用户的执行命名空间
self._globals={}
def后循环(自):
“处理任何未完成的事务。
尽管Cmd文档中有声明,Cmd.postloop()不是存根。
"""
cmd.cmd.postloop(self)##清理命令完成
打印“退出…”
def precmd(自身,管路):
“”“此方法在输入行之后调用,但在
它已被解释。如果要修改输入行
在执行之前(例如,变量替换),请在此处执行。
"""
如果行!='':
self.\u hist+=[line.strip()]
回程线
def POSTMD(自动、停止、线路):
“”“如果要停止控制台,请返回计算结果为true的内容。
如果您想执行一些命令后处理,请在此处执行。
"""
回程站
def默认值(自身,行):
当无法识别命令前缀时,在输入行上调用“”。
在这种情况下,我们将该行作为Python代码执行。
"""
尝试:
self.\u本地、self.\u全局中的执行(行)
除例外情况外,e:
打印e.uuuuuuuuuuuuuuuuuuuuuuuuuuu类:“,e
def emptyline(自):
“”“对空输入行不执行任何操作”“”
通过
def do_安装(自身、路径构建):
“”“安装[pathToBuild]
使用指定的文件“”安装
如果要生成路径:
打印“安装%s”%pathToBuild
其他:
print“您必须指定应该使用的文件的绝对路径!”
def do_配置(自我、路径配置):
“”“配置[pathToConfiguration]
使用指定的文件“”进行配置
如果路径配置:
打印“配置%s”%pathToConfiguration
其他:
print“您必须指定应该使用的文件的绝对路径!”
来自:

可选参数completekey是完成键的
readline
名称;它默认为
选项卡
。如果completekey不是
None
readline
可用,则命令完成将自动完成

您需要有
readline
,才能完成制表符


命令方法只接受一个参数,您需要在命令方法本身中解析该参数。当然,如果需要,您可以调用
self.do\u help()
self.help()
方法。

对于第一部分,是的,我发现cmd模块易于使用,功能强大,足以实现类似于Python内置命令提示符的CLI

对于第二部分的第一个问题,您需要告诉模块如何完成命令行,方法是实现类似complete_install(self、word、line、begindex、endindex)的方法,该方法获取行中的当前word、line、begin和end索引,并返回表示有效完成的字符串列表或元组。 通常,您应该根据当前单词(第一个参数)计算并过滤列表

例如,我使用命令'll'设置日志记录级别,实现如下:

def complete_ll(self, a, ln, bi, ei):
    return tuple(
        k for k in logging._nameToLevel.keys()
        if k.casefold().find(a.casefold()) >= 0)

def do_ll(self, a):
    "Set or get debug level: DL [10 .. 50 | levelName]"
    def ll():
        n = log.getEffectiveLevel()
        return f"{logging.getLevelName(n)} ({n})"
    print(ll())
    if a:
        try:
            log.setLevel(eval(a.upper(), logging._nameToLevel))
            print("Logging level changed to", ll())
        except Exception as e:
            log.exception(f"{e}, value {a}", exc_info=1)

对于第二个问题,是的,您应该检查“do_u…”方法中参数的数量、类型和有效性,在您的示例中已经做了一定程度的检查。当然,如果真的有帮助的话,您也可以在此时调用“help…”方法。

所以唯一的问题是,我在没有readline的windows上运行了这个方法?(因为我一改为Linux,它就工作了)。有关该问题的windows替代方法,请参阅。:-)
def complete_ll(self, a, ln, bi, ei):
    return tuple(
        k for k in logging._nameToLevel.keys()
        if k.casefold().find(a.casefold()) >= 0)

def do_ll(self, a):
    "Set or get debug level: DL [10 .. 50 | levelName]"
    def ll():
        n = log.getEffectiveLevel()
        return f"{logging.getLevelName(n)} ({n})"
    print(ll())
    if a:
        try:
            log.setLevel(eval(a.upper(), logging._nameToLevel))
            print("Logging level changed to", ll())
        except Exception as e:
            log.exception(f"{e}, value {a}", exc_info=1)