本文共 11142 字,大约阅读时间需要 37 分钟。
python 命令行界面
这是我的两部分系列文章的第二部分,这是有关具有出色的命令行UI的终端应用程序的。 在 ,我讨论了使命令行应用程序变得纯粹使用乐趣的功能。 在第二部分中,我将研究如何借助一些库在Python中实现这些功能。 在本文的最后,读者应该对如何使用 , (命令行界面创建工具包), 和有了一个很好的理解,以实现易于使用的 。
我计划用不到20行的Python代码来实现这一目标。 让我们开始。
我喜欢把这个库视为命令行应用程序的瑞士军刀,它可以代替 , 等。 让我们安装库并开始:
pip install prompt_toolkit
我们将从一个简单的REPL开始。 通常,REPL将接受用户输入,执行操作并打印结果。 对于我们的示例,我们将构建一个“ echo” REPL。 它仅打印出用户输入的内容:
from prompt_toolkit import prompt while 1 : user_input = prompt ( '>' ) print ( user_input )
这就是实现REPL所需要的全部。 它可以读取用户输入并打印出他们输入的内容。 此代码段中使用的提示函数来自hint_toolkit库。 它是readline库的替代品。
为了增强我们的REPL,我们可以添加命令历史记录:
from prompt_toolkit import prompt from prompt_toolkit. history import FileHistory while 1 : user_input = prompt ( '>' , history = FileHistory ( 'history.txt' ) , ) print ( user_input )
我们刚刚在REPL中添加了持久的历史记录。 现在,我们可以使用向上/向下箭头浏览历史记录,并使用Ctrl + R搜索历史记录。 这满足了命令行的基本礼节。
我在第一部分中介绍的可发现性技巧之一是自动建议历史记录中的命令。 (我们看到这个功能在鱼贝首创。)让我们增加这个功能对我们的REPL:
from prompt_toolkit import prompt from prompt_toolkit. history import FileHistory from prompt_toolkit. auto_suggest import AutoSuggestFromHistory while 1 : user_input = prompt ( '>' , history = FileHistory ( 'history.txt' ) , auto_suggest = AutoSuggestFromHistory ( ) , ) print ( user_input )
我们所要做的就是将一个新参数添加到hint() API调用中。 现在,我们有了一个REPL,它具有历史上的鱼式自动建议。
现在,让我们通过自动补全实现Tab补全的增强,当用户开始输入输入时,它会弹出可能的建议。
我们的REPL将如何知道建议? 我们提供了可能的建议项的词典。
假设我们正在为SQL实现REPL。 我们可以使用SQL关键字存储自动完成字典。 让我们看看如何做到这一点:
from prompt_toolkit import prompt from prompt_toolkit. history import FileHistory from prompt_toolkit. auto_suggest import AutoSuggestFromHistory from prompt_toolkit. contrib . completers import WordCompleter SQLCompleter = WordCompleter ( [ 'select' , 'from' , 'insert' , 'update' , 'delete' , 'drop' ] , ignore_case = True ) while 1 : user_input = prompt ( 'SQL>' , history = FileHistory ( 'history.txt' ) , auto_suggest = AutoSuggestFromHistory ( ) , completer = SQLCompleter , ) print ( user_input )
再一次,我们只需使用名为WordCompleter的提示工具包的内置完成例程, 即可将用户输入与可能的建议字典进行匹配,并提供一个列表。
现在,我们有了一个REPL,可以执行自动补全,历史记录中的鱼式建议以及历史记录的上/下遍历。 所有这些用不到10行的实际代码。
Click是一个命令行创建工具包,可轻松解析程序的命令行选项参数和参数。 本节不讨论如何使用Click作为参数解析器。 相反,我将看一下Click附带的一些实用程序。
安装click很简单:
pip install click
传呼机是Unix实用程序,一次可以显示较长的输出一页。 分页器的示例有less , more , most等。通过分页器显示命令的输出不仅是友好的设计,而且是一件很体面的事情。
让我们进一步看前面的例子。 除了使用默认的print()语句,我们还可以使用click.echo_via_pager() 。 这将通过寻呼机将输出发送到stdout。 它与平台无关,因此可以在Unix或Windows中使用。 click.echo_via_pager()会尝试为寻呼机使用适当的默认设置,以便在必要时能够显示颜色代码:
from prompt_toolkit import prompt from prompt_toolkit. history import FileHistory from prompt_toolkit. auto_suggest import AutoSuggestFromHistory from prompt_toolkit. contrib . completers import WordCompleter import click SQLCompleter = WordCompleter ( [ 'select' , 'from' , 'insert' , 'update' , 'delete' , 'drop' ] , ignore_case = True ) while 1 : user_input = prompt ( u 'SQL>' , history = FileHistory ( 'history.txt' ) , auto_suggest = AutoSuggestFromHistory ( ) , completer = SQLCompleter , ) click. echo_via_pager ( user_input )
我的上一篇文章中提到的好处之一是,当命令变得过于复杂时,它会退回到编辑器。 再次单击具有以启动编辑器,并将在编辑器中输入的文本返回给应用程序:
import click message = click. edit ( )
Fuzzy Finder是用户以最少的输入来缩小建议范围的一种方法。 再一次,有一个实现模糊查找器的库。 让我们安装库:
pip install fuzzyfinder
Fuzzy Finder的API很简单。 您传入部分字符串和可能的选项列表,然后Fuzzy Finder将使用按相关性顺序排列的模糊算法返回与部分字符串匹配的新列表。 例如:
>>> from fuzzyfinder import fuzzyfinder >>> suggestions = fuzzyfinder ( 'abc' , [ 'abcd' , 'defabca' , 'aagbec' , 'xyz' , 'qux' ] ) >>> list ( suggestions ) [ 'abcd' , 'defabca' , 'aagbec' ]
现在我们有了Fuzzyfinder ,让我们将其添加到SQL REPL中。 我们这样做的方法是定义一个自定义的完成程序,而不是提示工具包随附的WordCompleter 。 例如:
from prompt_toolkit import prompt from prompt_toolkit. history import FileHistory from prompt_toolkit. auto_suggest import AutoSuggestFromHistory from prompt_toolkit. completion import Completer , Completion import click from fuzzyfinder import fuzzyfinder SQLKeywords = [ 'select' , 'from' , 'insert' , 'update' , 'delete' , 'drop' ] class SQLCompleter ( Completer ) : def get_completions ( self , document , complete_event ) : word_before_cursor = document. get_word_before_cursor ( WORD = True ) matches = fuzzyfinder ( word_before_cursor , SQLKeywords ) for m in matches: yield Completion ( m , start_position = - len ( word_before_cursor ) ) while 1 : user_input = prompt ( u 'SQL>' , history = FileHistory ( 'history.txt' ) , auto_suggest = AutoSuggestFromHistory ( ) , completer = SQLCompleter ( ) , ) click. echo_via_pager ( user_input )
现在,让我们在用户输入中添加语法突出显示。 我们正在构建一个SQL REPL,并且拥有丰富多彩SQL语句会很好。
Pygments是一个语法高亮库,内置支持300多种语言。 添加语法高亮显示会使应用程序丰富多彩,这有助于用户在执行SQL之前先在SQL中发现错误,例如错别字,不匹配的引号或方括号。
首先安装Pygments:
pip install pygments
让我们使用Pygments为我们SQL REPL添加颜色:
from prompt_toolkit import prompt from prompt_toolkit. history import FileHistory from prompt_toolkit. auto_suggest import AutoSuggestFromHistory from prompt_toolkit. completion import Completer , Completion import click from fuzzyfinder import fuzzyfinder from pygments. lexers . sql import SqlLexer SQLKeywords = [ 'select' , 'from' , 'insert' , 'update' , 'delete' , 'drop' ] class SQLCompleter ( Completer ) : def get_completions ( self , document , complete_event ) : word_before_cursor = document. get_word_before_cursor ( WORD = True ) matches = fuzzyfinder ( word_before_cursor , SQLKeywords ) for m in matches: yield Completion ( m , start_position = - len ( word_before_cursor ) ) while 1 : user_input = prompt ( u 'SQL>' , history = FileHistory ( 'history.txt' ) , auto_suggest = AutoSuggestFromHistory ( ) , completer = SQLCompleter ( ) , lexer = SqlLexer , ) click. echo_via_pager ( user_input )
提示工具包可与Pygments库一起使用。 我们选择由Pygments提供的SqlLexer ,并将其传递给来自hint -toolkit的提示 API。 现在,所有用户输入都被视为SQL语句并进行了适当着色。
最后,我们完成了创建功能强大的REPL的旅程,该功能具有通用外壳程序的所有功能,例如历史记录,键绑定以及用户友好的功能,例如自动完成,模糊查找,分页器支持,编辑器支持和语法突出显示。 我们用不到20条Python语句实现了所有这些目标。
那不是那么容易吗? 现在,您没有任何借口不编写出色的命令行应用程序。 这些资源可能会帮助:
在Amjith Ramanujam的演讲, (5月20日在俄勒冈州波特兰)中了解更多信息。
翻译自:
python 命令行界面
转载地址:http://ewpzd.baihongyu.com/