【Python 軍火庫 - Click👆】一「點」就通的CLI使用者互動介面

2023/11/14閱讀時間約 6 分鐘
raw-image


Python雖然是直譯式的腳本語言, 用起來非常方便, 但當我們的工具越發成熟時, 就會需要將使用方式、介面給設計好, 那通常都會用來處理後端伺服器的作業, 也比較面向IT端, 因此我們通常會以Command Line的形式與使用工具的人進行互動, 而內建模組雖然有「argparse」可以讓我們簡易的設計Command Line相關輸入參數, 但隨著我們的功能越來越完善之後, 命令列參數的配置就會有機會擴增到幾十甚至幾百個, 而為了讓每個功能更加明確, 我們會希望有分組的功能, 分成子群命令, 但簡單的「argparse」較難以達成, 且較不直觀。

既然內建的「argparse」不容易滿足我們的需求, 那該怎麼辦呢? 沒關係, Python發展已經有一段時間了, 過程也累積了許多前輩的需求與經驗, 而在這邊我們要推薦一個「click」的套件, 他可以幫助我們在設計Command Line介面時更加直觀, 就讓我們來好好了解一下吧!

在進入主題之前我們先來說說它究竟有什麼優點吧, 這部份是親自使用後發現的一些重點:

  • 說明文件直接搭配函式的docstring進行呈現, 非常直觀, 不用一份註解寫兩次。
  • 直接與function綁定,一眼就能明白參數目的。
  • 容易嵌套,不用一堆專為CLI介面設計的腳本。

好了,廢話不多說, 就讓我們進入本章節的主題吧!

基本框架與必要元素

裝飾器、入口函式、執行函式

# test.py
@click.command()
@click.option(...)
def run(...):
"""
"""

run()

這裡是一個完整的範本: test.py

import click

@click.command()
@click.option('--msg')
def run(msg: str):
print(msg)

run()

實際執行看看…

python test.py --help

Usage: test.py [OPTIONS]

Options:
--msg TEXT
--help Show this message and exit.

以上就是Click的基本使用方式, 相信看到這邊是不是覺得蠻容易的呢?

平價的argparse V.S 奢華的click

為了讓大家更有感, 我們就肉身來實作一下argparse與click兩個方式撰寫起來的差異, 就以上個章節為例來進行對比。

首先是argparse的部份, 我們可以發現到步驟總共有3個步驟, 分別是「設計解析器 → 定義參數 → 解析參數」。

import argparse

# step 1: 設計解析器
parser = argparse.ArgumentParser()

# step 2: 定義參數
parser.add_argument('--msg')

def run():
# step 3: 解析參數
args = parser.parse_args()
print(args.msg)

run()

我們再看看click的部份, 可以發現到它僅需要定義參數, 省去了「設計解析器」與「解析參數」的部份, 主要是將這兩個步驟封裝於裝飾器之中, 因此看起來會稍微簡潔一些。

import click

# step 1: 定義參數
@click.command()
@click.option('--msg')
def run(msg: str):
print(msg)

run()

版本號資訊小技巧

這邊會跟大家分享一下我們在設計版本號參數「--version」時, 透過click可以怎麼做? 那麼首先我們可以撰寫一個回傳版本號字串的函式。

def version_msg():
return '0.0.1'

接著我們透過「version_option」這個函式來進行版本號的互動功能。

@click.command()
@click.version_option(version=version_msg(), prog_name='clitest')
def start():
"""
"""

if __name__ == '__main__':
start()
raw-image

查閱使用說明的📚 Help

我們可以透過context_settings來設定查閱說明的參數, 也就是我們常常在使用程式的「-h」、「--help」, 那我們來翻翻官方文件, 可以看到「這裡」有提到, 我們可以透過dictionary的方式帶入參數設定, 具體可以這麼做。

CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])

@click.command(
context_settings=CONTEXT_SETTINGS,
)

結語

這一個篇章主要在介紹我們常見的cli是怎麼設計的, 雖然基礎的argparse基本上簡單的程式已經足夠使用了, 但通常我們的功能會越發強大, 而使用者需要輸入的參數也會越來越多, 甚至需要將各功能需要的參數進行群組化, 那麼簡單的argparse肯定是不夠看的, 故此我們才介紹了click這套輔助工具, 而我們之後也會針對click的進階技巧進行分享, 敬請期待後續的篇章。

如果您需要的是一個完整從無到有的cli設計教學, 歡迎參閱「【🔒 Python 先修班】👆 打造友善的使用者互動CLI介面」, 我們會帶您手把手的建構一個您專屬的cli程式。

您是否苦於網路資訊爆炸嗎? 教學何其多,但卻無法好好選擇的困境呢? 歡迎加入「🔒 阿Han的軟體心法實戰營」, 這裡不給您冗餘的雜訊, 單刀直入直接送您重點, 避開選擇障礙的困境, 讓您獲得業界標準的開發起手式, 成為Top 1的頂尖人才。

91會員
260內容數
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
留言0
查看全部
發表第一個留言支持創作者!