Google 開源的 Python 命令行庫(kù):初探 fire
一、前言
在本系列前面所有文章中,我們分別介紹了 argparse、docopt 和 click 的主要功能和用法。它們各具特色,都能出色地完成命令行任務(wù)。argparse 是面向過程的,需要先設(shè)置解析器,再定義參數(shù),再解析命令行,最后實(shí)現(xiàn)業(yè)務(wù)邏輯。docopt 先用聲明式的語(yǔ)法定義出參數(shù),再過程式地解析命令行和實(shí)現(xiàn)業(yè)務(wù)邏輯。click 則是用裝飾器的方式進(jìn)一步簡(jiǎn)化顯式的命令調(diào)用邏輯,但仍然不夠面向?qū)ο蟆?/p>
而今天要介紹的 fire則是用一種面向廣義對(duì)象的方式來玩轉(zhuǎn)命令行,這種對(duì)象可以是類、函數(shù)、字典、列表等,它更加靈活,也更加簡(jiǎn)單。
本系列文章默認(rèn)使用 Python 3 作為解釋器進(jìn)行講解。若你仍在使用 Python 2,請(qǐng)注意兩者之間語(yǔ)法和庫(kù)的使用差異哦~
二、介紹
fire 可以根據(jù)任何 Python 對(duì)象自動(dòng)生成命令行接口。它有如下特性:
- 能以簡(jiǎn)單的方式生成 CLI
- 是一個(gè)開發(fā)和調(diào)試 Python 代碼的實(shí)用工具
- 能將現(xiàn)存代碼或別人的代碼轉(zhuǎn)換為 CLI
- 使得在 Bash 和 Python 間的轉(zhuǎn)換變得更容易
- 通過預(yù)先為 REPL 設(shè)置所需的模塊和變量,使得實(shí)用 REPL 更加容易
通過如下命令可快速安裝 fire 庫(kù):
- pip install fire
三、快速開始
回憶下使用 argparse、docopt 和 click 實(shí)現(xiàn)命令行程序的步驟:
- 對(duì)于 argparse 來說,要先設(shè)置解析器,再定義參數(shù),再解析命令行,最后實(shí)現(xiàn)業(yè)務(wù)邏輯(四步)
- 對(duì)于 docopt 來說,要先定義定義接口描述,再解析命令行,最后實(shí)現(xiàn)業(yè)務(wù)邏輯(三步)
- 對(duì)于 click 來說,就是實(shí)現(xiàn)業(yè)務(wù)邏輯和通過裝飾器的方式定義參數(shù)(兩步)
它們的實(shí)現(xiàn)步驟越來越簡(jiǎn)單,從四步簡(jiǎn)化到了兩步。而今天的主角 fire 只需一步,現(xiàn)業(yè)務(wù)邏輯就夠了。
這簡(jiǎn)直簡(jiǎn)單的不可思議,為什么這樣做就夠了?我們不妨考慮下 Python 中的函數(shù),函數(shù)是不是可以對(duì)應(yīng)一個(gè)命令行程序,而函數(shù)的參數(shù)可以對(duì)應(yīng)命令行程序的參數(shù)和選項(xiàng)呢?再看看 Python 中的類,一個(gè)類是不是可以對(duì)應(yīng)一個(gè)命令行程序,而類中的每個(gè)實(shí)例方法就可以對(duì)應(yīng)子命令,實(shí)例方法中的參數(shù)就是對(duì)應(yīng)子命令的參數(shù)和選項(xiàng)。
這么一想,理論上確實(shí)是可以實(shí)現(xiàn)的,我們不妨通過下面的示例來看看 fire 是如何讓我們通過簡(jiǎn)單的方式實(shí)現(xiàn)命令行程序。
3.1 使用函數(shù)
來看這么一個(gè)例子:
- import firedef hello(name="World"): return 'Hello
- {name}!'.format(name=name)if __name__ == '__main__':
- fire.Fire(hello)
在上述例子中定義一個(gè) hello 函數(shù),它接受 name 參數(shù),并且有默認(rèn)值 "World"。使用 fire.Fire(hello) 即可非常簡(jiǎn)單快速地實(shí)現(xiàn)命令功能,這個(gè)命令行就接受 --name 選項(xiàng),不提供時(shí)使用默認(rèn)值 "World",提供時(shí)就按提供的值來。
可在命令行中執(zhí)行下列命令:
- $ python hello.pyHello World!$ python hello.py --name=ProdesireHello
- Prodesire!$ python hello.py --helpINFO: Showing help with the
- command 'hello.py -- --help'.NAME hello.pySYNOPSIS hello.py
- <flags>FLAGS --name=NAME
3.2 使用類
使用函數(shù)是最簡(jiǎn)單的方式,如果我們想以更有組織的方式來實(shí)現(xiàn),比如使用類,fire 也是支持的。
- import fireclass Calculator(object): """A simple calculator
- class.""" def double(self, number): return 2 * number def
- triple(self, number): return 3 * numberif __name__ == '__main__':
- fire.Fire(Calculator)
在上述例子中定義一個(gè) Calculator 類,它有兩個(gè)實(shí)例方法 double 和 triple,并且都接受 number 參數(shù),沒有默認(rèn)值。使用 fire.Fire(Calculator) 即可非常簡(jiǎn)單快速地實(shí)現(xiàn)命令功能,這個(gè)命令行支持兩個(gè)子命令 double 和 triple,位置參數(shù) NUMBER 或選項(xiàng)參數(shù) --number
可在命令行中執(zhí)行下列命令:
- $ python calculator.py double 1020$ python calculator.py triple
- --number=1545$ python calculator.py double --helpINFO: Showing help with
- the command 'calculator.py double -- --help'.NAME calculator.py
- doubleSYNOPSIS calculator.py double NUMBERPOSITIONAL ARGUMENTS
- NUMBERNOTES You can also use flags syntax for POSITIONAL ARGUMENTS
四、小結(jié)
fire 的使用方式非常簡(jiǎn)單,定一個(gè) Python 對(duì)象,剩下的就交給 fire 來處理,可謂是非常的 Pythonic,這也是它會(huì)如此受歡迎的原因。
除了上面展示的內(nèi)容,fire 還支持更多種類的 Python 對(duì)象,也擁有很多強(qiáng)大的功能,我們將在接下來幾節(jié)中逐步走近它。