4 个用于构建优秀的命令行用户界面的 Python 库
在这个分为两篇的关于具有绝佳命令行界面的终端程序的系列文章的第二篇教程中,我们将讨论 Prompt、Toolkit、Click、Pygments 和 Fuzzy Finder 。
这是我的一个分为两篇的关于具有绝佳命令行界面的终端程序的系列文章的第二篇教程。在第一篇文章中,我们讨论了一些能够使命令行应用用起来令人感到愉悦的特性。在第二篇文章中,我们来看看如何用 Python 的一些库来实现这些特性。
我打算用少于 20 行 Python 代码来实现。让我们开始吧。
Python Prompt Toolkit
我习惯于把这个库称为命令行应用的瑞士军刀,它可以作为 readline 、curses 等的替代品。让我们首先安装这个库,然后开始该教程:
pip install prompt_toolkit
我们以一个简单的 REPL (LCTT 译注:REPL —— Read-Eval-Print Loop,交互式开发环境)开始。一个典型的 REPL 会接收用户的输入,进行一个操作,然后输出结果。比如在我们的例子中,我们将要实现一个具有 “回显” 功能的 REPL 。它仅仅是原样打印出用户的输入:
REPL
from prompt_toolkit import promptwhile 1:user_input = prompt('>')print(user_input)
这就是实现 REPL 的全部代码。它可以读取用户的输入,然后打印出用户的输入内容。在这段代码中使用的 prompt 函数来自 prompt_toolkit 库,它是 readline 库的一个替代品。
命令历史
为了增强我们的 REPL 的功能,我们可以添加命令历史:
from prompt_toolkit import promptfrom prompt_toolkit.history import FileHistorywhile 1:user_input = prompt('>',history=FileHistory('history.txt'),)print(user_input)
我们刚刚给 REPL 添加了持久的命令历史。现在,我们可以使用上/下箭头来浏览命令历史,并使用 Ctrl-R 来搜索命令历史。它满足了命令行的基本准则。
自动推荐
在第一篇教程中,我讲到的一个可发现性技巧是自动推荐历史命令。(我是首先在 fish shell 中看到的这一特性)让我们把这一特性加入到我们的 REPL 中:
from prompt_toolkit import promptfrom prompt_toolkit.history import FileHistoryfrom prompt_toolkit.auto_suggest import AutoSuggestFromHistorywhile 1:user_input = prompt('>',history=FileHistory('history.txt'),auto_suggest=AutoSuggestFromHistory(),)print(user_input)
我们只需要给 prompt() API 调用添加一个新的参数。现在,我们有了一个具有 fish shell 风格的 REPL,它可以自动推荐历史命令。
自动补全
现在,让我们通过自动补全来加强 Tab 补全。它能够在用户开始输入的时候弹出可能的命令推荐。
REPL 如何来进行推荐呢?我们使用一个字典来进行可能项的推荐。
比如说我们实现一个针对 SQL 的 REPL 。我们可以把 SQL 关键字存到自动补全字典里面。让我们看一看这是如何实现的:
from prompt_toolkit import promptfrom prompt_toolkit.history import FileHistoryfrom prompt_toolkit.auto_suggest import AutoSuggestFromHistoryfrom prompt_toolkit.contrib.completers import WordCompleterSQLCompleter = 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)
再次说明,我们只是简单的使用了 prompt-toolkit 内建的一个叫做 WordCompleter 的补全特性,它能够把用户输入和可能推荐的字典进行匹配,然后提供一个列表。
现在,我们有了一个能够自动补全、fish shell 风格的历史命令推荐以及上/下浏览历史的 REPL 。实现这些特性只用了不到 10 行的实际代码。
Click
Click 是一个命令行创建工具包,使用它能够更容易的为程序解析命令行选项的参数和常量。在这儿我们不讨论如何使用 Click 来作为参数解析器。相反,我们将会看看 Click 带有的一些功能。
安装 Click:
pip install click
分页器
分页器是 Unix 系统上的实用工具,它们能够一次一页地显示很长的输出。分页器的一些例子包括 less、more、most 等。通过分页器来显示一个命令的输出不仅仅是一个友好的设计,同时也是必要的。
让我们进一步改进前面的例子。我们不再使用默认的 print() 语句,取而代之的是 click.echo_via_pager() 。它将会把输出通过分页器发送到标准输出。这是平台无关的,因此在 Unix 系统或 Windows 系统上均能工作。如果必要的话,click_via_pager 会尝试使用一个合适的默认分页器来输出,从而能够显示代码高亮。
from prompt_toolkit import promptfrom prompt_toolkit.history import FileHistoryfrom prompt_toolkit.auto_suggest import AutoSuggestFromHistoryfrom prompt_toolkit.contrib.completers import WordCompleterimport clickSQLCompleter = 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)
编辑器
在我前面的文章中一个值得一提的细节是,当命令过于复杂的时候进入编辑器来编辑。Click 有一个简单的 API 能够打开编辑器,然后把在编辑器中输入的文本返回给应用。
import clickmessage = click.edit()
Fuzzy Finder
Fuzzy Finder 是一种通过少量输入来为用户减少推荐的方法。幸运的是,有一个库可以实现 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 中。方法是我们自定义一个 completer 而不是使用来自 prompt-toolkit 库的 WordCompleter 。比如:
from prompt_toolkit import promptfrom prompt_toolkit.history import FileHistoryfrom prompt_toolkit.auto_suggest import AutoSuggestFromHistoryfrom prompt_toolkit.completion import Completer, Completionimport clickfrom fuzzyfinder import fuzzyfinderSQLKeywords = ['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)
Pygments
现在,让我们给用户输入添加语法高亮。我们正在搭建一个 SQL REPL,如果具有彩色高亮的 SQL 语句,这会很棒。
Pygments 是一个提供语法高亮的库,内建支持超过 300 种语言。添加语法高亮能够使应用变得彩色化,从而能够帮助用户在执行程序前发现 SQL 中存在的错误,比如拼写错误、引号不匹配或括号不匹配。
首先,安装 Pygments :
pip install pygments
让我们使用 Pygments 来为 SQL REPL 添加颜色:
from prompt_toolkit import promptfrom prompt_toolkit.history import FileHistoryfrom prompt_toolkit.auto_suggest import AutoSuggestFromHistoryfrom prompt_toolkit.completion import Completer, Completionimport clickfrom fuzzyfinder import fuzzyfinderfrom pygments.lexers.sql import SqlLexerSQLKeywords = ['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)
Prompt Toolkit 能够和 Pygments 一同很好的工作。我们把 Pygments 提供的 SqlLexer 加入到来自 prompt-toolkit 的 prompt 中。现在,所有的用户输入都会被当作 SQL 语句,并进行适当着色。
结论
我们的“旅途”通过创建一个强大的 REPL 结束,这个 REPL 具有常见的 shell 的全部特性,比如历史命令,键位绑定,用户友好性比如自动补全、模糊查找、分页器支持、编辑器支持和语法高亮。我们仅用少于 20 行 Python 代码就实现了这个 REPL 。
不是很简单吗?现在,你没有理由不会写一个自己的命令行应用了。下面这些资源可能有帮助:
- Click (命令行界面创建工具)
- Fuzzy Finder
- Prompt Toolkit
- 在
prompt-toolkit的仓库中查看 Prompt Toolkit 教程 和例子 - Pygments
你也可以在我在 PyCon US 2017 的演讲优秀的命令行工具中学到更多东西,该会议是 5 月 20 日在波特兰,俄勒冈举行的。
4 个用于构建优秀的命令行用户界面的 Python 库的更多相关文章
- 如何编写一个带命令行参数的Python文件
看到别人执行一个带命令行参数的python文件,瞬间觉得高大上起来.牛逼起来,那么如何编写一个带命令行参数的python脚本呢?不用紧张,下面将简单易懂地让你学会如何让自己的python脚本,支持带命 ...
- 一个简单、易用的Python命令行(terminal)进度条库
eprogress 是一个简单.易用的基于Python3的命令行(terminal)进度条库,可以自由选择使用单行显示.多行显示进度条或转圈加载方式,也可以混合使用. 示例 单行进度条 多行进度条 圆 ...
- 区分命令行模式和Python交互模式
命令行模式 在Windows开始菜单选择"命令提示符",就进入到命令行模式,它的提示符类似C:\> Python交互模式 在命令行模式下敲命令python,就看到类似如下的一 ...
- 命令行下查看python和numpy的版本和安装位置
命令行下查看python和numpy的版本和安装位置 1.查看python版本 方法一: python -V 注意:‘-V‘中‘V’为大写字母,只有一个‘-’ 方法二: python --versio ...
- 命令行模式和python交互模式
一.命令行模式 在Windows开始菜单选择“命令提示符”,就进入到命令行模式,它的提示符类似C:>:. 二.Python交互模式 在命令行模式下敲命令python,就看到类似如下的一堆文本输出 ...
- python如何通过windows命令行运行一个python程序文件?
python如何通过windows命令行运行一个python程序文件? cmd 进入到py文件对应目录下或者直接在上面的文件地址栏输入cmd,敲入回车 定位到对应的目录下 输入python xxx.p ...
- 在命令行中输入python会跳转到商店问题解决,python环境变量的配置
安装python出了点问题,明明安装了,在应用商店显示已获取,可是在命令行输入python检验时就直接跳转到win10系统自带的应用商店...... 这不免让我怀疑是不是没有安装好python~但是它 ...
- 使用Cli构建Go的命令行应用
转载出处:http://www.opscoder.info/cli.html 在Go里面应用中flag这一标准库,提供了很多我们在写命令行时需要的interface,然而如果你需要更强大更好的结构 ...
- 构建一个Flowable命令行应用
官网链接 [(https://flowable.com/open-source/docs/bpmn/ch02-GettingStarted/#building-a-command-line-appli ...
随机推荐
- java面试⑤前端部分
2.4.1 简单说一下HTML,CSS,javaScript在网页开发中的定位? 2.4.2简单介绍一下AJAX 2.4.3 JS和JQuery的关系 2.4.4 JQuery的常用选择器 2.4.5 ...
- C学习笔记(1)-结构体、预处理与多文件结构程序设计
一.结构体的定义与使用 #include <stdio.h> //定义结构体(类似模板) typedef struct { char name[50]; int age; char add ...
- org.springframework.web.context.ContextLoaderListener 解决办法
最近部署ssm项目在tomcat,tomcat启动的时候发出org.springframework.web.context.ContextLoaderListener 错误 严重: Error con ...
- [android] 手机卫士黑名单功能(列表展示)
先把要拦截的电话号码保存到数据库中,拦截模式用个字段区分,1 电话拦截,2 短信拦截,3全部拦截 新建Activity类CallSmsSafeActivity.java 新建布局文件activity_ ...
- JSTL判断list是否为空
1.先在jsp页面中导入下列类库. <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" ...
- [源码] 定义String s="abcd", 求长度
一般会答: s.length() 看源码是如何实现的: /** * Returns the length of this string. * The length is equal to the nu ...
- Centeros7下安装Mysql 2018最新版,非常简单
下载Mysql的rpm安装包 shell> wget http://dev.mysql.com/get/ mysql-community-release-el7-5.noarch.rpm安装sh ...
- 微软官方公布的Windows 8.1 Update常用快捷键
以前用 Windows Server 2008R2,初装Win8.1,感觉最明显的是开关机速度真心快~下面摘录了常用的几个快捷键: Windows 键+D:显示或隐藏桌面 Windows键+X:访问Q ...
- 开包即食的教程带你浅尝最新开源的C# Web引擎Blazor
在今年年初,恰逢新春佳节临近的时候.微软给全球的C#开发者们,着实的送上了一分惊喜.微软正式开源Blazor,将.NET带回到浏览器. 这个小惊喜,迅速的在dotnet开发者中间传开了.201 ...
- javascript中让你捉摸不定的this
this到底指向谁,估计很多人在使用javascript的过程中都遇到过,这个关键字如果没搞懂,在一些高级功能中都会困难重重,搜了下相关文章,介绍的都挺多的,也有很深入的,比如汤姆大叔的<深入理 ...