有时,我们必须使用命令提示符终端来编写命令,这个终端解释为各种目的编写的内联命令,称为命令解释器。我们可以编写和构建一个框架,用来编写面向行的命令解释器,为了完成这个任务,有时我们必须使用类。一个为命令解释器提供框架以便我们可以编写面向行的命令的类被称为 cmd 类。现在,我们很多人想知道 cmd 类的用途是什么,它对我们有什么帮助。cmd 类对于创建原型、稍后将包装的测试工具以及以更复杂的方式呈现的管理工具非常有用。因此,要执行所有这些任务并创建这些工具,我们必须使用命令行界面,这可以使用 cmd 类轻松构建。
命令行解释器的使用已经变得非常罕见,因为现在大多数应用中的图形用户界面已经增加。因此,用户更倾向于只使用这些应用,而不是使用简单的面向行的命令解释器,但是使用命令行界面有其自身的优势。
以下是使用命令行界面或解释器的几个优点:
- 这些命令行解释器没有任何基于图形用户界面的界面;这就是为什么远离更便宜的计算机的 CPU 和内存资源也是可用的。
- 用命令行解释器创建一个面向文本的文档非常容易,而且我们可以非常快速地创建它。
- 由于命令行解释器是可移植的,因此,我们可以在任何设备的任何地方运行它们。
- 在命令行解释器中打开一个文件非常容易,而且这种方法比进入驱动程序和在菜单中搜索文件要快得多。
这些是命令行解释器的一些主要优点,这就是为什么即使在今天,大多数用户也更喜欢它们,而不是许多基于图形用户界面的应用,这些应用的界面更有吸引力。看到这些优点后,我们可以理解并得出结论,用 cmd 类构建命令行解释器是多么有用。它不仅对我们的职业生活和职业任务有帮助,而且对我们的个人项目也有帮助。听到 cmd 类也出现在 Python 包中,我们中的许多人都会感到惊讶,因此可以使用 Python 程序为命令行界面创建一个框架。我们将学习 Python 中的 CmdParser 模块,在这个模块中我们将看到 cmd 类的使用,我们将使用这个模块为命令行解释器构建一个框架。
Python 中的 CmdParser 模块
Cmdparser Module 是一个 Python 包,其中包含两个子模块,这对我们编写文本命令解析器和创建命令行界面框架非常有用。CmdParser 模块中也使用了这个的 cmd 类&函数,我们将在程序中使用这些函数构建一个解析树来执行名称匹配操作。Python 中的 CmdParser 模块使用 Python 的内置 cmd 模块,并调用它来创建命令行界面的框架。
Python 的 CmdParser 模块包含以下两个子模块或 Python 包:
- 日期时间屁股
- cmdparser
在本教程中,我们将学习 Cmdparser 包的两个子模块的实现和工作方式,并在 Python 程序中使用它们来创建一个简单的解析树。
CmdParser 模块:安装
如果我们想在 Python 程序中使用 Cmdparser Module 的函数和子模块,我们应该确保这个模块存在于我们的系统中,因为它不是 Python 的内置模块。因此,如果 CmdParser 模块还没有出现在我们的系统中,我们必须安装它,以进一步推进其子模块的实现部分。我们可以通过各种安装过程来安装 Cmdparser Module,但是在这里我们将使用 pip 安装程序来执行此任务,因为这是最简单易行的方法。
在终端 Shell 中写下以下命令,通过 pip 安装程序在我们的系统中安装 CmdParser 模块:
pip install cmdparser
写完上面给出的命令后,我们必须按回车键并等待一段时间,因为成功安装这个模块需要一段时间。
正如我们所看到的,CmdParser 模块现在已经成功安装在我们的系统中,现在,我们可以通过将它导入程序来使用它及其子模块。我们将首先查看 cmdparser 包的 Cmdparser 子模块的概述和实现,然后我们将浏览 datetimeparser 子模块的概述。
CmdParser 模块:cmdparser 子模块概述:
Python 的 cmdparser 包中的 Cmdparser 子模块允许我们在文本命令规范的帮助下创建解析树结构,如下所示:
fries( scam | ham [eggs] | peas [omelette [...]] )
我们可以使用解析树结构来检查这个特定的命令字符串。cmdparser 子模块还允许我们验证要为解析树列出的部分命令字符串的完成情况。让我们通过使用上面列出的文本命令规范从 Python 程序中创建一个解析树来理解这个概念。
示例:看看下面的 Python 程序,我们从 cmdparser 子模块创建了一个解析树,然后将令牌与解析树进行匹配:
# Import cmdparser package from cmdparser module
from cmdparser import cmdparser
# Creating a sample parse tree
parseTree = cmdparser.parse_spec("abcd (efgh|ijkl) [qrst]")
# Matching tokens from parse tree
parseTree.check_match(("abcd", "efgh", "something"))
parseTree.check_match(("abcd", "efgh", "anything", "uvwx")) # Will throw an error
# Completing parse tree in the output
parseTree.get_completions(("abcd", ))
输出:
"command invalid somewhere in: 'uvwx'"
{'efgh', 'ijkl'}
说明:
我们首先从 cmdparser 包中导入 cmdparser 子模块,在程序中创建一个带有标记的解析树。之后,我们使用 cmdparser 包中的 parse_spec()函数在 parse tree 变量中创建了一个示例解析树。在解析树中,我们只定义了静态标记,并在以后用于匹配。之后,我们使用 cmdparser 包的 parsematch()来匹配我们定义的解析树中的标记。在第二个匹配中,解析树将抛出一个错误,因为“uvwx”不是包中定义的静态标记。最后,我们使用 parse completions()函数来完成解析树中的其余标记。该函数将在输出中打印解析树的其余静态标记。
现在,正如我们在输出中所看到的,解析中剩余的静态标记被打印出来,在此之前,还打印了一个“uvwx”标记的错误。
我们在解析中使用了静态标记,这是我们在上面给出的示例中创建的,但是我们也可以使用 CmdParser 模块在动态标记的帮助下创建解析树。当我们创建一个包含动态标记的解析树时,我们可以在接受字符串列表的地方设置动态标记,并且动态标记中的字符串列表会随着时间而变化。我们还可以使用动态令牌,在处理固定令牌字符串时,可以接受任意字符串或字符串列表。如果我们想查看 CmdParser 模块中所有可用于设置动态令牌的类的规范,我们可以检查该模块的文档字符串。在这里,我们将通过使用 CmdParser 模块类创建一个带有动态标记的解析树来理解这一点。看看下面的例子,我们使用来自 CmdParser 模块的动态标记创建了一个解析树。
示例 2: 看看下面的 Python 程序,其中我们创建了一个带有动态标记的解析树,以接受字符串的动态列表:
# Import cmdparser from Cmdparser module
from cmdparser import cmdparser
# Class having fruit names as token
class tokenOfFruit(Cmdparser.Token):
def get_values(self, context):
return ["watermelon", "melon", "orange", "grapes", "lichi", "mango", "apple", "banana", "strawberry", "guava", "greenapple"] # Tokens of class with fruit name values
# Default function for identification
def myIdentfictionFactory(token):
if token == "number":
return Cmdparser.IntegerToken(token) # If token is a number
elif token == "fruit":
return tokenOfFruit(token) # If token is a fruit name
return None
# Creating a parse tree with fruit and number token in it
parseTree = Cmdparser.parse_spec("keep <fruit>packet", ident_factory = myIdentfictionFactory)
cmdFields = {}
# Matching with the parse tree
parseTree.check_match(("keep", "26", "mango", "packet"), fields = cmdFields)
parseTree.check_match(("keep", "all", "orange", "packet"))
# Getting completions from the parse tree
parseTree.get_completions(("keep", "24",))</fruit>
输出:
"'all' is not a valid "
{'apple',
'banana',
'grapes',
'greenapple',
'guava',
'lichi',
'mango',
'melon',
'orange',
'strawberry',
'watermelon'}
说明:
从 Cmdparser Module 导入 cmdparser 子模块包后,我们创建了一个类,其中水果名称作为程序中解析树的标记。我们在‘token offurits’类中定义的水果名称将作为解析树的静态标记,为了从该类中检索水果名称的值,我们在该类中定义了一个默认函数。然后,我们定义了另一个函数(myIdentificationFactory),它将在解析树中接受动态标记,并将接受数值(数字)作为匹配值。为了设置带有数值的动态标记,我们使用了 Cmdparser 包中的 IntegerToken()函数,因此它将使这成为一个动态标记,它将接受任何整数值作为解析树中的匹配值。之后,我们使用 parse_spec()函数创建解析树,将数字和水果作为动态标记,将“keep”和“packet”作为静态标记。然后,我们使用 checkmatch()函数,并在其中给出标记值,以便从解析树中执行匹配操作。我们可以在输出中看到,当我们没有提供数字时,它会抛出一个匹配错误。最后,当我们对解析树使用 get completions()函数时,所有用作标记的水果值都会打印在输出中。
cmdparser 子模块中的类:
以下是 cmdparser 子包中可用的四个类,它们适合作为创建用户派生令牌(静态和动态)的基类:
- Token: Token 是来自 cmdparser 子包的基类,当固定值集合中的一个适合我们正在创建的解析树时,它非常有用。在解析树中,字符串值列表可以是静态的,也可以是动态的,这个类可以用来创建和接受标记。如果我们想从结果的解析树中返回一个有效标记列表作为字符串列表,我们必须重写 get_values()方法。
- AnyToken: 这个基类类似于子包的 Token 类,但是在使用 AnyToken 基类时,任何字符串都应该出现在结果中。如果我们想要执行令牌的验证,我们可以通过子模块中可用的 validate()方法来完成。但是,在使用 validate()方法之前,我们应该注意 validate()方法不允许制表符结束,因为它只在整个命令被解析的过程中被调用。AnyToken 基类在调用字符串列表(静态和动态)时也需要 convert()方法。
- AnyTokenString: 就两个基类执行的功能而言,AnyTokenString 基类与 AnyToken 类非常相似。但是,在 AnyTokenString 类中,我们在命令行上定义的值的所有剩余项都在解析过程中被使用。
- Subtree:cmd parser 子包中的子树基类匹配我们创建的解析树中的整个命令,并将匹配过程的结果与字典字段中指定的令牌进行比较。使用子树类时,我们必须将命令规范字符串传递给类的构造器,然后类型类将重写 convert()方法来解释命令。
CmdParser 模块:datetimeparser 子模块概述:
Cmdparser 包中的 Datetimeparser 子模块在创建解析树时添加了一些特定的标记类型,这将有助于解析与日期和时间格式相关的人类可读规范。在 datetimeparser 子模块中,指定了绝对和相对日期类型,并且这些类型也可以在需要和适当的时候转换为其他实例。
以下是 datetimeparser 子模块中日期类型的示例:
- 2020 年 11 月 2 日
- 上周周四 01: 28 等。
日期计时器子模块中的类:
以下是 CmdParser 模块的 datetimeparser 子包中的五个可用类,适合作为创建用户派生令牌(静态和动态)的基类:
- TimeSubtree:datetime arser 子模块的 TimeSubtree 类用于解析解析树中以 12 或 24 小时格式给出的一天中的时间。解析给定时间后的返回值在 time.localtime()函数的帮助下返回。
- datetime subtree:来自 datetimeparser 子模块的 datetime subtree 类的行为类似于 TimeSubtree 类。DateSubtree 类包括不同日期格式的文本,即一周中与当天(上周星期一)相关的天数、文本日期(01-11-2021)、描述性日期版本(01-11-2021)以及今天、昨天和明天以及解析日历日期。在 DateSubtree 类的情况下,返回值是分析树中的 datetime.date 实例。
- DateTimeSubtree: 在阅读了 datetimeparser 子模块的前两个基类的描述后,我们可以通过名字得到 DateTimeSubtree 类的基本思路。DateTimeSubtree 类从解析树中给定的日期和时间解析规范。DateTimeSubtree 接受 TimeSubtree 和 DateSubtree 短语的组合或者 RelativeTimeSubtree 类的一个短语(我们将在接下来阅读这个类)来解析日期和时间的规范。如果短语来自 RelativeTimeSubtree 类,则根据给定的时间以相对格式计算时间。DateTimeSubtree 类的返回值是 datetime.datetime 实例值。
- RelativeTimeSubtree: 来自 datetimesubtree 子模块的 RelativeTimeSubtree 基类从包装类返回作为其返回值。RelativeTimeSubtree 类用于解析格式中给出的短语,该格式指示相对于当前时间的时间偏移,例如两天前、三小时前等。RelativeTimeSubtree 类的返回值是 cmdparser 的一个实例。datetime delta 类(来自 datetimeparser 子模块的包装类)包含一个 datetime.timedelta 实例。
- class calendarperiodsubtree:class calendarperiodsubtree 是 datetimeparser 子模块的最后一个基类,它解析过去给出的日历周期的规范。在此类的情况下,返回值是 datetime.date 的 2 元组实例,它以返回值格式表示以下内容:从日历中指定的日期范围,其中范围中的第一个日期是包含的,范围中的第二个日期是排除的,等等。
结论
在本教程中,我们阅读了关于 CmdParser 模块的内容,并了解了如何使用该模块的包来创建 cmdparser 的接口。我们在 Python 中了解了 cmdparser 包的 Cmdparser 和 datetimeparser 子模块,以及它们如何有助于为解析树创建标记。最后,我们查看了 Cmdparser 包的两个子模块的基类,并了解了这些类如何有助于解析为解析树的标记给出的规范。