📜  Python中的 Cmdparse 模块

📅  最后修改于: 2022-05-13 01:54:28.655000             🧑  作者: Mango

Python中的 Cmdparse 模块

为编写面向行的命令解释器提供简单框架的类称为 cmd 类。这些对于稍后将被包装在更复杂的界面中的管理工具、原型和测试工具通常很有用。使用 cmd 模块可以轻松制作命令行界面。
如今,图形用户界面的使用如此之多,以至于命令行解释器似乎过时了。命令行界面有几个优点:

  • 命令行界面是可移植的,可以在任何地方运行。
  • CPU 和内存资源远比 GUI 界面便宜。
  • 使用命令行打开文件比进入驱动程序和搜索菜单更容易。
  • 创建面向文本的文档要快得多。

命令类

该模块只定义了一个类:Cmd 类。命令行解释器是创建子类 cmd.Cmd 类。 Cmd 实例或子类实例可以被视为面向行的解释器框架。

  • 创建命令:在解释器提示下输入的一行文本的第一部分是命令。 identchars成员字符包含的最长字符串是 Command。
    非重音字母、数字和下划线符号是默认标识符。行尾是命令的参数。
  • 参数: do_xxx方法只需要多取一个参数,对应于用户在命令名后面输入的字符串部分。
  • 错误:解释器使用以下格式来表示错误:
*** : 
  • 返回值:在最常见的情况下:命令不应返回值。当您想退出解释器循环时,任何返回真值的命令都会停止解释器是一个例外。
    例子:
Python3
def add(self, d):
    k = d.split()
    if len(k)!= 2:
       print "*** invalid number of arguments"
       return
    try:
       k = [int(i) for i in k]
    except ValueError:
       print "*** arguments should be numbers"
       return
    print k[0]+k[1]


Python3
from cmdparser import cmdparser
 
parse_tree = cmdparser.parse_spec("abc (def|ghi)  [mno]")
 
# Returns None to indicate
# successful parse
parse_tree.check_match(("abc", "def", "anything"))
 
# Returns an appropriate
# parsing error message
parse_tree.check_match(("abc", "ghi", "anything", "pqr"))
 
# Returns the list ["def", "ghi"]
parse_tree.get_completions(("abc", ))


Python3
from cmdparser import cmdparser
 
 
class fruitToken(cmdparser.Token):
     
    def get_values(self, context):
        # Static list here, but could
        # easily be dynamic
        return ["raspberry", "orange", "mango",
                "grapes", "apple", "banana"]
 
def my_ident_factory(token):
     
    if token == "number":
        return cmdparser.IntegerToken(token)
     
    elif token == "fruit":
        return fruitToken(token)
     
    return None
 
parse_tree = cmdparser.parse_tree("take   bags",
                                  ident_factory = my_ident_factory)
 
# Returns None to indicate successful
# parse, and the "cmd_fields" dict will
# be initialised as:
# { "take": ["take"], "": ["23"],
#   "": ["apple"], "bags": ["bags"] }
cmd_fields = {}
 
parse_tree.check_match(("take", "23",
                        "apple", "bags"),
                       fields = cmd_fields)
 
# Returns an appropriate
# parsing error message
parse_tree.check_match(("take", "all",
                        "raspberry", "bags"))
 
# Returns the list ["raspberry",
# "orange", "mango", ..., "banana"]
parse_tree.get_completions(("take", "5"))


Python3
from cmdparser import cmdparser
 
@cmdparser.CmdClassDecorator()
class CommandHandler(cmd.Cmd):
 
    @cmdparser.CmdMethodDecorator():
    def do_command(self, args, fields):
        """command ( add | delete ) 
 
        The example explains the use of
        command to demonstrate use of the cmd
        decorators.
        """
 
        # Method body - it will only be called
        # if a command parses successfully according
        # to the specification above.


Cmdparse 模块

cmdparser 包包含两个可用于编写文本命令解析器的模块。
该模块特别使用内置的Python cmd 模块。该软件包由两个模块组成:

  • cmdparser.cmdparser
  • cmdparser.datetimeparse

安装

我们可以从 PyPI 安装 cmdparse 包。例如

pip install cmdparse

cmdparse 概述

Cmd 模块允许从文本命令规范创建解析树,如下所示

chips( spam | ham [eggs] | beans [eggs [...]] )

可以使用这些分析树检查特定的命令字符串。此外,它允许列出部分命令字符串的有效完成。
例子:

Python3

from cmdparser import cmdparser
 
parse_tree = cmdparser.parse_spec("abc (def|ghi)  [mno]")
 
# Returns None to indicate
# successful parse
parse_tree.check_match(("abc", "def", "anything"))
 
# Returns an appropriate
# parsing error message
parse_tree.check_match(("abc", "ghi", "anything", "pqr"))
 
# Returns the list ["def", "ghi"]
parse_tree.get_completions(("abc", ))

输出:

python-cmdparse-1

可以设置动态令牌,其中接受的字符串列表可以随时间变化,或者在处理固定令牌字符串时可以接受任意字符串或字符串列表。检查模块的文档字符串以获取可用类的详细信息,但作为示例:

Python3

from cmdparser import cmdparser
 
 
class fruitToken(cmdparser.Token):
     
    def get_values(self, context):
        # Static list here, but could
        # easily be dynamic
        return ["raspberry", "orange", "mango",
                "grapes", "apple", "banana"]
 
def my_ident_factory(token):
     
    if token == "number":
        return cmdparser.IntegerToken(token)
     
    elif token == "fruit":
        return fruitToken(token)
     
    return None
 
parse_tree = cmdparser.parse_tree("take   bags",
                                  ident_factory = my_ident_factory)
 
# Returns None to indicate successful
# parse, and the "cmd_fields" dict will
# be initialised as:
# { "take": ["take"], "": ["23"],
#   "": ["apple"], "bags": ["bags"] }
cmd_fields = {}
 
parse_tree.check_match(("take", "23",
                        "apple", "bags"),
                       fields = cmd_fields)
 
# Returns an appropriate
# parsing error message
parse_tree.check_match(("take", "all",
                        "raspberry", "bags"))
 
# Returns the list ["raspberry",
# "orange", "mango", ..., "banana"]
parse_tree.get_completions(("take", "5"))

输出:

python-cmdparser-2

有四个类可用,它们是用户派生令牌的合适基类:

  • 令牌:当一组固定值合适时,这很有用,其中列表可能是固定的或动态的。应该重写 get_values() 方法以将有效标记列表作为字符串返回。
  • Anytoken:与Token类似,但可以是任意字符串。验证可以通过 validate() 方法执行,但 validate() 方法不允许制表符补全,因为它仅在整个命令被解析后才被调用。如果需要,还有一个 convert() 方法
  • AnyTokenString:与 AnyToken 类似,但命令行上剩余的所有项目都被消耗。
  • 树:它匹配整个命令子树,并将结果与字段字典中的指定标记相匹配。命令规范字符串应该传递给构造函数,类型类将覆盖 convert() 方法并以某种方式解释命令(尽管这是严格可选的)。
    装饰器与派生自 cmd.Cmd 的命令处理程序一起使用,它允许从文档字符串帮助文本中自动提取命令字符串,并允许将命令解析和完成添加到类的命令处理方法中。
    实现了 do_XXX() 形式的各种方法来实现 cmd.Cmd 类。

Python3

from cmdparser import cmdparser
 
@cmdparser.CmdClassDecorator()
class CommandHandler(cmd.Cmd):
 
    @cmdparser.CmdMethodDecorator():
    def do_command(self, args, fields):
        """command ( add | delete ) 
 
        The example explains the use of
        command to demonstrate use of the cmd
        decorators.
        """
 
        # Method body - it will only be called
        # if a command parses successfully according
        # to the specification above.

日期时间分析概述

  • Datetimeparse 模块添加特定的标记类型来解析人类可读的日期和时间规范。指定了绝对和相对两种类型的日期,并酌情将其转换为其他实例。
    一些例子是
1:35 on friday last week
11 feb 2019
  • 当前定义的类是:
    • DateSubtree:它包括字面量日期(2020-03-14)、与当天相关的星期几(上周星期六)、描述性版本(2019 年 6 月 26 日)以及昨天、今天和明天以及解析日历日期.返回值为 datetime.date 实例。
    • TimeSubtree: TimeSubtree 解析 12 或 24 小时格式的时间。返回值与 time.localtime() 返回的值相同。
    • RelativeTimeSubtree:返回值是 cmdparser.DateDelta 的一个实例,它是一个包含 datetime.timedelta 的包装类。它解析表示与当前时间的时间偏移的短语,例如 3 天和 2 小时前。
    • DateTimeSubtree: datetime.datetime 实例是返回值。DateTimeSubtree 解析日期和时间的规范,接受 DateSubtree 和 TimeSubtree 短语的组合,或 RelativeTimeSubtree 短语;在后一种情况下,时间是相对于当前时间计算的。
    • CLassCalenderPeriodSubtree:解析过去日历周期的规范。返回的值是 datetime.date 实例的 2 元组,表示指定的日期范围,其中第一个日期包括在内,第二个日期不包括在内。