天天看點

四個Python庫,實作超實用的指令行功能

四個Python庫,實作超實用的指令行功能

在二部曲系列文章的第二部分關于偉大的指令行 ui 終端應用文章中,我們探索了“提示工具包”,“指令行界面建立工具包“,“pygments”和“模糊搜尋”。

這是我的二部曲終端應用程式與偉大的指令行界面的第二部分。 在第一篇文章中,我介紹了幾個能使使用指令行程式充滿樂趣的功能。

在第二部分中,我将介紹如何在幾個 python 庫的幫助下實作這些功能。 在本文結尾,讀者應該很好地了解如何使用 prompt

toolkit,click(指令行界面建立工具包),pygments 和 fuzzy finder 來實作一個易于使用的

repl(互動式解釋器)。

我計劃用少于 20 行的 python 代碼中實作這一點。 讓我們開始。

python 提示工具包

我喜歡将這個庫看作是像瑞士軍刀那樣集大成者的指令行應用程式,它可以替代 readline,curses 等等。 讓我們來安裝這個庫并開始使用:

pip install prompt_toolkit 

我們将從簡單的 repl 開始。 通常 repl 将接受使用者輸入,執行操作并列印結果。 對于我們的例子,我們要建構一個“echo”repl。 它隻是列印出使用者輸入的内容:

互動式解釋器

from prompt_toolkit import prompt 

while 1: 

user_input = prompt('>') 

print(user_input) 

這就是實作 repl 所需要的。它可以讀取使用者輸入并列印輸入的内容。此代碼段中使用的提示函數來自 prompt_toolkit 庫;它是 readline 庫的替代者。

曆史記錄

為了增強我們的repl,我們可以添加曆史指令:

from prompt_toolkit.history import filehistory 

    user_input = prompt('>', 

                        history=filehistory('history.txt'), 

                       ) 

    print(user_input) 

我們剛剛向repl添加了持久的曆史記錄。現在我們可以使用向上/向下箭頭浏覽曆史記錄,并使用 ctrl + r 搜尋曆史。這符合指令行的基本習慣。

自動提示

我在第一部分中介紹的技巧之一是自動提示曆史指令。(我們看到這個功能最先在 fish shell中推出。)讓我們把這個功能添加到我們的repl中:

from prompt_toolkit.auto_suggest import autosuggestfromhistory 

                        auto_suggest=autosuggestfromhistory(), 

我們隻需要在 prompt() api 調用中添加一個新的參數。現在我們的 repl 已經可以支援類似 fish shell 那樣的曆史指令自動提示功能了。

自動補全

現在我們通過 tab 增強來實作自動補全,當使用者開始鍵入輸入時,它彈出可能的建議。

我們的 repl 是如何知道要給出什麼提示的? 我們提供了一個可能名目提示的字典。

假設我們正在為 sql 實作 repl。我們可以使用 sql 關鍵字存儲我們的自動完成字典。讓我們看看如何做到這一點:

from prompt_toolkit.contrib.completers import wordcompleter 

sqlcompleter = wordcompleter(['select', 'from', 'insert', 'update', 'delete', 'drop'], 

                             ignore_case=true) 

    user_input = prompt('sql>', 

                        completer=sqlcompleter, 

                        ) 

再次,我們隻需使用一個名為 wordcompleter 的 prompt-toolkit 的内置例程,它将使用者輸入與可能提示的字典進行比對,并提供一個清單。

我們現在有一個 repl,它可以自動補全,fish 式的曆史提示,以及曆史指令的上下浏覽。 所有這些都在不到 10 行的實際代碼中。

指令行界面建立工具包

click 是一個指令行建立工具包,可以友善地解析程式的指令行選項參數和參數。 本節不介紹如何作為參數解析器使用click;取而代之的是我将研究一些 click 庫的其他功能的。

安裝 click 很簡單

pip install click 

分頁器

分頁器是在 unix 上用來一次性長輸出顯示的實用程式。分頁器包括一些 less, more, most等。通過分頁器顯示指令不僅僅是友好的設計,而且也是需要的。

讓我們進一步來看以上的例子。我們可以用 click.echo_via_pager() 來代替預設的 print()

語句。這将通過分頁器将輸出傳遞給 stdout,這和平台無關,是以可以在 windows 或者 unix

上運作。click.echo_via_pager() 将嘗試用預設的分頁器來輸出,以便在需要的時候顯示有顔色的代碼:

import click 

    user_input = prompt(u'sql>', 

    click.echo_via_pager(user_input) 

編輯器

在我之前的文章中提到一個細節,就是當指令變得太複雜時就會回到編輯器,同樣的 click 提供了一個簡單的 api 可以來啟動編輯器,并将編輯器中輸入的文本傳回到應用中:

message = click.edit() 

模糊搜尋

模糊搜尋是一種讓使用者通過最少的輸入來縮小提示。同樣有一個模糊搜尋庫,讓我們安裝這個庫:

pip install fuzzyfinder 

模糊搜尋的api很簡單,你傳遞進部分字元串和一個可能選擇的清單,模糊搜尋将傳回一個新的清單,它和使用了按相關性排序的迷糊算法的字元串進行比對,例如:

>>> from fuzzyfinder import fuzzyfinder 

>>> suggestions = fuzzyfinder('abc', ['abcd', 'defabca', 'aagbec', 'xyz', 'qux']) 

>>> list(suggestions) 

['abcd', 'defabca', 'aagbec'] 

現在我們有了模糊搜尋,我們将它加入到我們的 sql 互動式解釋器中。這樣就定義了一個完成器,而不是 prompt-toolkit 附帶的 wordcompleter。例如:

from prompt_toolkit.completion import completer, completion 

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)) 

                        completer=sqlcompleter(), 

pygments

現在我們來給使用者輸入添加文法高亮顯示。我們正在建構 sql 互動式解釋器,并且擁有彩色的 sql 語句會很好。

pygments 是一個文法高亮庫,内置支援300多種語言。添加文法高亮使得應用程式變成彩色的,可以幫助使用者在執行 sql 之前發現一些例如打字錯誤或者無法比對的引号和括号。

首先安裝 pygments

pip install pygments 

讓我們用 pygments 給我們的 sql 互動式解釋器添加顔色:

from pygments.lexers.sql import sqllexer 

                        lexer=sqllexer, 

提示工具包适用于 pygments 庫。我們選擇 pygments 提供的 sqllexer 并将其從提示工具包傳遞給 api 。現在所有的使用者輸入都會被當作 sql 語句并且添上了顔色。

結論

我們本次成果的結論是通過建立一個強大的互動式解釋器,擁有常見 shell 的所有功能,例如曆史記錄,鍵綁定,和很友好的自動完成,模糊搜尋,分頁器,編輯器和文法高亮的功能。我們用少于 20 個 python 語句實作了所有這些。

不是很容易嗎?現在你還有什麼理由寫不出一個優秀的指令行應用程式呢,這裡有一些可能有幫助的資源:

click (指令行界面建立工具包)

提示工具包

請參閱 prompt toolkit 教程和 prompt-toolkit 中的例子

2017年5月20日,amjith ramanujam在俄勒岡州波特蘭市舉辦的美國 2017 pycon 大會上做了名為《超棒的指令行工具》的演講,你可以通過這個演講了解更多内容。

作者:佚名

來源:51cto