當前位置:
首頁 > 最新 > 用Click編寫Python命令行工具

用Click編寫Python命令行工具

在編寫Python命令行(CLI)應用程序時,使用Click庫進行參數解析的深入教程

Python通常被稱為膠水語言,因為它非常靈活,並且能夠與現有的程序很好地聯結在一起。 這意味著很大一部分Python代碼被編寫為腳本和命令行界面(CLI)。

構建這些命令行界面和工具是非常強大的,因為它使得幾乎所有的東西都可以自動化。 因此,隨著時間的推移,CLI可能變得相當複雜。

通常從一個非常簡單的腳本開始,運行這些python代碼來完成一件特定的事情。例如:訪問web API並將輸出列印到控制台:

僅通過python print_user_agent.py你就可以運行它,它就會列印出 API調用的user-agent。

正如我所說,一個非常簡單的腳本。

但是,當這樣一個Python命令行腳本變得越來越複雜時,你有什麼選擇?

這就是我們將在整個教程中看到的內容。您將學習關於Python中構建CLI的基本知識,以及Click如何使其成為更好的體驗。

我們將使用這些知識,並從簡單的腳本一步一步地通過命令行參數、選項及有用的用法說明CLI。所有這些都使用了一個叫做click的框架。

在本教程的最後,你會知道:

為什麼click相比於argparse和optparse來說是一個更好的選擇

如何用它創建一個簡單的CLI

如何將強制命令行參數添加到您的腳本

如何解析命令行標誌和選項

如何通過添加幫助(使用)文本,使命令行應用程序更加便於用戶使用。

而且你也會看到如何用最少量的代碼來實現所有的功能。

順便說一下,本教程中的所有代碼示例都使用Python 3.6。它們可能不適用於Python的早期版本,但是如果遇到任何麻煩,請在下面留言,我們將把它整理在一起。

讓我們開始吧!

為什麼要編寫Python命令行腳本和工具?

上面的代碼片段僅僅是一個例子,在現實生活中並不是很有用。我在Python開發人員的職業生涯中編寫的腳本要複雜得多。它們通常幫助構建,測試和部署應用程序,並使流程可重複。

您可能有自己的經驗,並知道這可能是我們日常工作的一大部分:有些腳本仍然保留在你們所構建的項目中,有些對其他團隊或項目都有用,甚至可以擴展更多的功能。

在這些情況下,使腳本更加靈活或者可以使用命令行參數進行配置變得非常重要。它使得向腳本提供伺服器名稱,憑證或任何其他信息成為可能。

這就是像optparse和argparse這樣的Python模塊,讓你的生活變得更輕鬆。但是,在我們仔細研究這些之前,讓我們直接說一下我們的術語。

命令行介面的基礎知識

命令行界面(CLI)以可執行文件的名稱開頭。您可以在控制台中鍵入它的名稱,並訪問腳本的主要入口點,例如pip。

根據CLI的複雜性,通常可以將參數傳遞給腳本,可以是:

1.參數,它是傳遞給腳本的必需參數。如果您不提供它,CLI將返回一個錯誤。例如,click是這個命令中的參數:pip install click。

2.或者它可以是一個選項,它是一個可選的(||)參數,結合名稱和值部分,如--cache-dir ./my-cache。你告訴CLI應將./my-cache值用作緩存目錄。

3.一個特殊選項是啟用或禁用特定行為的標誌。最常見的可能是 --help。您只需指定名稱,CLI將在內部解釋該值

使用更複雜的CLI(例如pip或Heroku Toolbelt),您可以訪問集合入口的功能。它們通常被稱為命令子命令

當你使用pip install

安裝Python包時,您可能已經使用了CLI。命令install會告訴CLI您將訪問該功能來安裝軟體包,並使你能訪問該特性的參數。

Python 3.x標準庫中提供的命令行框架

將命令和參數添加到腳本中是非常強大的,但命令行的解析並不像您想像的那樣直截了當。 你應該使用已經解決了這個問題的Python的軟體包之一,來替代你自己寫。

兩個最著名的軟體包是optparse和argparse。 它們是遵循「包含電池」原則的Python標準庫的一部分。

他們大多提供相同的功能且使用代碼非常相似。 最大的不同在於,optparse自Python 3.2以來已被棄用,argparse被認為是在Python中實現CLI的標準

你可以在Python文檔中找到更多關於它們的詳細信息,來讓你知道一個argparse腳本是什麼樣子的,下面是一個例子:

click vs argparse:一個更好的選擇?

你可能正在看上面的代碼示例,在想「這些東西是什麼意思?」這正是我在使用argparse遇到的一個問題:它不直觀,很難閱讀。

這就是為什麼我愛上了click

click正在解決與optparse和argparse相同的問題,但使用方法稍微不同。它使用裝飾器的概念。這需要命令是可以使用裝飾器包裝的函數。

丹寫了一個很好的介紹,如果這是你第一次聽到這個詞,或許你想快速學習。

作者Armin Ronacher詳細描述了他為什麼寫這個框架。您可以閱讀文檔中的「Why Click?」部分,我鼓勵您看一下。

我使用click的主要原因是你可以使用少量代碼輕鬆構建功能豐富的CLI。即使您的CLI增長並且變得更加複雜,代碼也很容易閱讀。

通過Click構建一個簡單的Python命令行界面

我已經談了很多CLI和框架。我們來看看用click來構建一個簡單的CLI是什麼意思。與本教程中的第一個示例類似,我們可以創建一個簡單的基於click的CLI,它向控制台列印一些東西。這並不是很費力:

首先,我們現在不用擔心最後兩行,當文件作為腳本執行時,這只是Python(稍微不直觀)的方式來運行主函數。

正如你所看到的,我們所要做的就是創建一個函數並添加@ click.command()裝飾器。 這將它變成一個click命令,這是我們的腳本的主要入口點。 你現在可以在命令行上運行它,你會看到類似這樣的東西:

click 之所以比較美觀是因為,我們免費獲得一些額外的功能。 我們沒有實現任何幫助功能,但添加了--help選項,您將看到一個列印到命令行的基本幫助頁面:

Click更實際的PythonCLI示例

現在你已經知道click是如何使得建立一個簡單的CLI更容易了,我們將看一個稍微更現實的例子。我們將構建一個允許我們與Web API 進行交互的程序。最近每個人都會使用,它們讓我們訪問一些更酷的數據。

本教程其餘部分將介紹的API是OpenWeatherMap API。 它提供當前天氣以及特定位置的五天預報。 我們將從他們的API示例返回當前天氣的位置。

在開始編寫代碼之前,我喜歡嘗試使用API來更好地理解它是如何工作的。 我想你應該知道的一個工具是HTTPie,我們可以使用它來調用示例API並查看返回的結果。 你甚至可以嘗試他們的在線終端來運行它,無需安裝。

讓我們來看看當我們將API中的位置設置為london時會發生什麼:

如果你正在用這樣的面孔查看屏幕因為上面的例子包含一個API密鑰,所以不要擔心這是他們提供的示例API密鑰。

上面例子中比較重要的一點是,我們發送兩個查詢參數(使用HTTPie時用==表示)來獲取當前天氣:

q是我們的地點名稱;

appid是我們的API密鑰。

這使我們可以使用Python和Requests庫創建一個簡單的實現(為簡單起見,我們將忽略錯誤處理和失敗請求)。

這個函數使用兩個查詢參數向天氣API發出一個簡單的請求。 它需要一個強制的參數location,它被假定為一個字元串。 我們還可以通過在函數調用中傳遞api_key來提供API密鑰。 它是可選的,可以使用示例鍵作為默認值。

這裡是我們目前倫敦的天氣,形成Python REPL:

click 解析一個必選參數

簡單的current_weather函數允許我們使用用戶提供的自定義位置來構建我們的CLI。 我希望它能像這樣工作:

你可能已經猜到了,這次調用的位置就是我之前介紹的一個參數。 這是因為它是我們天氣CLI的強制性參數。

我們如何在Click中實現? 這很簡單,我們使用一個名為參數的裝飾器。 誰會想到?

我們先來看一個簡單的例子,通過定義參數的位置來修改它。

你可以看到,我們所要做的就是添加一個額外的裝飾器到我們的主要功能,並給它一個名字。Click使用該名稱作為變數傳遞到包裝函數的參數中。

在我們的例子中,命令行參數location的值將作為位置參數傳遞給主函數。有道理吧?

你也可以在你的名字中使用破折號( - ),例如api-key,在這個函數中,Click會將名字的中劃線變為下劃線。例如main(api_key)。

main的實現只需使用我們的current_weather函數來獲取CLI調用者提供的位置的天氣。 然後我們使用一個簡單的列印語句輸出天氣信息||

完成!

如果這個列印語句對你來說看起來很奇怪,那是因為這是一種用Python 3.6+格式化字元串的新方法,稱為f-string格式。 你應該查看 「Python中進行字元串格式化的4種主要方法」來了解更多。

cllick 解析可選參數

你可能已經找到了我們上面使用的示例API的一個小小的缺陷,你是一個聰明人

是的,這是一個靜態的端點,從2017年1月起總是返回倫敦的天氣。所以讓我們用一個真實的API密鑰來請求實際的API。

我們需要改變的第一件事是當前天氣的URL端點。 我們可以通過在OpenWeatherMap文檔中將current_weather函數中的url替換為端點來實現:

我們剛剛做出的更改將會破壞我們的CLI,因為默認API密鑰對真實API無效。 該API將返回一個401 UNAUTHORIZED HTTP狀態碼。 不相信我? 這是證明:

所以讓我們添加一個新的參數給我們的CLI,允許我們指定API密鑰。 但首先,我們必須決定這應該是一個參數還是一個選項。

我們使它成為一個option,因為添加一個像--api-key這樣的命名參數使得它更加明確和自描述。

以下是我認為用戶應該運行它的方式:

很好很容易。 所以讓我們看看我們如何將它添加到我們現有的click命令。

再來一次,我們正在為我們的main函數添加一個裝飾器。 這一次,我們使用非常直觀的命名@ click.option,並添加了我們的option名稱,包括前雙破折號( -- )。 正如你所看到的,我們也可以用一個短劃線( - )來提供一個快捷方式來保存用戶的一些輸入。

我之前提到,click從較長的版本創建傳遞給主函數的參數。 在option的情況下,它將劃破前面的破折號並將其變成snake_case的情況。 --api-key變成api_key。

我們必須做的最後一件事是將API密鑰傳遞給我們的current_weather函數。

我們使CLI用戶可以使用自己的密鑰並查看任何位置:

看著我的窗口,我可以證實這是真的。

將自動生成的使用說明添加到您的Python命令行工具中

你可以安慰自己,你已經用最少量的Boilerplate_code構建了一個很棒的小CLI。但是在你休息或者享受一杯飲料之前, 通過添加一些文檔,讓我們確保一個新的用戶能夠知道如何運行我們的小CLI ...(不要跑,超級簡單的。)

首先讓我們來看看在我們做了所有更改之後,--help標誌將會顯示什麼。 正如你所看到的,所有努力都不是白費力的:

我們想要解決的第一件事是我們的API密鑰選項丟失的描述。 我們所要做的就是向@click.option裝飾器提供一個幫助文本:

我們要做的第二個也是最後一個更改是添加整個click命令的文檔。 而最簡單的方式就是添加一個文檔字元串到我們的main函數。 是的,我們應該這樣做,所以這不是額外的工作:

綜合起來,我們的天氣工具得到了非常好的輸出。

我希望在這一點上,你感覺到了當我第一次發現click時的感覺:

帶有click的Python CLI:摘要&回顧

好的,我們已經在本教程中介紹了大量的內容。 現在是您為自己感到自豪的時候了。 以下是你所學到的:

為什麼click是一個更好的選擇相對argparse和optparse

如何用它創建一個簡單的CLI

如何將強制命令行參數添加到您的腳本

如何解析命令行標誌和選項;

如何通過添加幫助(使用)文本使您的命令行應用程序更加用戶友好

而所有這些都是用最少量的引用! 下面的完整代碼示例說明了這一點。你可以自由地使用它來做你自己的實驗

如果這啟發了你,你應該看看click官方文檔以獲得更多的功能。 您也可以查看我在2016 PyCon US 關於click的介紹。或者留意我的後續教程,您將在其中學習如何為我們的天氣CLI添加更多高級功能。

開心的CLI編碼!

英文原文:https://dbader.org/blog/python-commandline-tools-with-click#intro

譯者:韓曉


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

從小白到大神,一文讓你掌握 Python 基礎知識點

TAG:Python |