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", ))
输出:
可以设置动态令牌,其中接受的字符串列表可以随时间变化,或者在处理固定令牌字符串时可以接受任意字符串或字符串列表。检查模块的文档字符串以获取可用类的详细信息,但作为示例:
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"))
输出:
有四个类可用,它们是用户派生令牌的合适基类:
- 令牌:当一组固定值合适时,这很有用,其中列表可能是固定的或动态的。应该重写 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 元组,表示指定的日期范围,其中第一个日期包括在内,第二个日期不包括在内。
- DateSubtree:它包括字面量日期(2020-03-14)、与当天相关的星期几(上周星期六)、描述性版本(2019 年 6 月 26 日)以及昨天、今天和明天以及解析日历日期.返回值为 datetime.date 实例。