Python?Fire實(shí)現(xiàn)自動(dòng)生成命令行接口
命令行程序是平時(shí)寫(xiě)一些小工具時(shí)最常用的方式。
為了讓命令行程序更加靈活,我們常常會(huì)設(shè)置一些參數(shù),根據(jù)參數(shù)讓程序執(zhí)行不同的功能。
這樣就不用頻繁的修改代碼來(lái)執(zhí)行不同的功能。
隨著命令行程序功能的豐富,也就是參數(shù)多了以后,解析和管理參數(shù)之間的關(guān)系會(huì)變得越來(lái)越繁重。
而本次介紹的 Fire 庫(kù),正好可以解決這個(gè)問(wèn)題。
使用 Fire 庫(kù),我們只要關(guān)心具體功能的實(shí)現(xiàn),最后Fire會(huì)幫助我們自動(dòng)把所有功能組織成一個(gè)命令行程序。
Fire庫(kù)在github上的地址:github.com/google/python-fire
1. 一般命令
一般的命令,也就是帶有幾個(gè)參數(shù)的一段程序,比如:
# -*- coding:utf-8 -*-
def import_file(fp):
print("import file from: {}".format(fp))
def export_file(fp):
print("EXPORT file to: {}".format(fp))這是模擬文件導(dǎo)出功能的兩個(gè)函數(shù)。
使用 Fire 轉(zhuǎn)換成命令行程序非常簡(jiǎn)單,下面介紹幾種常用的方式。
1.1. 默認(rèn)方式
# -*- coding:utf-8 -*-
import fire
def import_file(fp):
print("IMPORT file from: {}".format(fp))
def export_file(fp):
print("EXPORT file to: {}".format(fp))
if __name__ == "__main__":
# fire默認(rèn)會(huì)將所有函數(shù)轉(zhuǎn)換成子命令
fire.Fire()然后,就可以通過(guò)子命令的方式執(zhí)行導(dǎo)入導(dǎo)出功能。
$ python main.py import_file --fp ./path/xxx.csv IMPORT file from: ./path/xxx.csv $ python main.py export_file --fp ./path/xxx.csv EXPORT file to: ./path/xxx.csv
函數(shù)的名稱自動(dòng)變?yōu)?strong>子命令的名稱,函數(shù)的參數(shù)自動(dòng)變成子命令的參數(shù)。
1.2. Fire<fn>
Fire庫(kù)的默認(rèn)方式會(huì)把所有的函數(shù)都轉(zhuǎn)換為子命令,如果只想導(dǎo)出一個(gè)函數(shù)的話,可以用 Fire<fn>的方式。
if __name__ == "__main__":
# 只導(dǎo)出 import_file 函數(shù)作為子命令
fire.Fire(import_file)只導(dǎo)出一個(gè)函數(shù)的時(shí)候,執(zhí)行命令的時(shí)候不需要輸入子命令的名稱。
$ python main.py --fp ./path/xxx.csv
IMPORT file from: ./path/xxx.csv
1.3. Fire<dict>
導(dǎo)出多個(gè)函數(shù)作為子命令時(shí),默認(rèn)是使用函數(shù)名作為子命令名稱的,函數(shù)名稱有時(shí)候會(huì)非常長(zhǎng),輸入很麻煩。
這時(shí),可以用 Fire<dict> 方式。
if __name__ == "__main__":
# 子命令的名稱分別是:import 和 export
fire.Fire({
"import": import_file,
"export": export_file,
})執(zhí)行時(shí),使用簡(jiǎn)化的子命令名稱。
$ python main.py import --fp ./path/xxx.csv
IMPORT file from: ./path/xxx.csv
$ python main.py export --fp ./path/xxx.csv
EXPORT file to: ./path/xxx.csv
這種方式非常靈活,不僅可以設(shè)置子命令名稱,還可以控制需要導(dǎo)出哪些函數(shù)。
1.4. Fire<object>
除了導(dǎo)出函數(shù),Fire<object>方式也可以導(dǎo)出對(duì)象的公有方法。
import fire
class FileHandler():
def __init__(self):
pass
def import_file(self, fp):
print("IMPORT file from: {}".format(fp))
def export_file(self, fp):
print("EXPORT file to: {}".format(fp))
if __name__ == "__main__":
fh = FileHandler()
fire.Fire(fh)使用方式如下:
$ python main.py import_file --fp ./path/xxx.csv
IMPORT file from: ./path/xxx.csv
$ python main.py export_file --fp ./path/xxx.csv
EXPORT file to: ./path/xxx.csv
使用對(duì)象的方式?jīng)]有直接使用函數(shù)那么簡(jiǎn)單,但有個(gè)好處是可以在初始化時(shí)傳入一些狀態(tài)。
import fire
import os
class FileHandler():
def __init__(self, folder=""):
self.folder = folder
def import_file(self, fp):
print("IMPORT file from: {}".format(os.path.join(self.folder, fp)))
def export_file(self, fp):
print("EXPORT file to: {}".format(os.path.join(self.folder, fp)))
if __name__ == "__main__":
# 設(shè)置了默認(rèn)文件夾,使用時(shí)直接傳入文件名即可
fh = FileHandler("./default_path")
fire.Fire(fh)$ python main.py import_file --fp xxx.csv
IMPORT file from: ./default_path/xxx.csv
$ python main.py export_file --fp xxx.csv
EXPORT file to: ./default_path/xxx.csv
1.5. Fire<class>
Fire<class>的方式也可以直接作用在類上,不用初始化對(duì)象。
if __name__ == "__main__":
fire.Fire(FileHandler)和 Fire<object> 不同的是,__init__方法的參數(shù)也變成了命令的參數(shù),也可以在命令行中調(diào)整了。
$ python main.py import_file --fp xxx.csv
IMPORT file from: xxx.csv
$ python main.py import_file --fp xxx.csv --folder ./my_folder
IMPORT file from: ./my_folder/xxx.csv
2. 組合命令
當(dāng)功能越來(lái)越多時(shí),可能就會(huì)需要組合一些功能一起運(yùn)行,省得輸入一個(gè)一個(gè)的子命令。
class FileHandler():
def __init__(self, folder="./defalut_dir"):
self.folder = folder
def import_file(self, fp):
print("IMPORT file from: {}".format(os.path.join(self.folder, fp)))
def export_file(self, fp):
print("EXPORT file to: {}".format(os.path.join(self.folder, fp)))
class DatabaseHandler():
def __init__(self, src="aliyun-mysql", dst="tecent-mysql"):
self.src = src
self.dst = dst
def import_db(self):
print("IMPORT data from: {} to: {}".format(self.src, self.dst))
def export_db(self):
print("EXPORT data from: {} to: {}".format(self.src, self.dst))
# 組合 FileHandler 和 DatabaseHandler
class ComposeHandler():
def __init__(self):
self.fh = FileHandler()
self.dh = DatabaseHandler()
def import_all(self, fp):
self.fh.import_file(fp)
self.dh.import_db()
def export_all(self, fp):
self.fh.export_file(fp)
self.dh.export_db()
if __name__ == "__main__":
fire.Fire(ComposeHandler)導(dǎo)出組合命令之后,不僅可以執(zhí)行組合命令,也可以只執(zhí)行子命令。
$ python main.py import_all --fp xxx.csv
IMPORT file from: ./defalut_dir/xxx.csv
IMPORT data from: aliyun-mysql to: tecent-mysql
$ python main.py export_all --fp xxx.csv
EXPORT file to: ./defalut_dir/xxx.csv
EXPORT data from: aliyun-mysql to: tecent-mysql
$ python main.py fh export_file --fp xxx.csv
EXPORT file to: ./defalut_dir/xxx.csv
$ python main.py dh export_db
EXPORT data from: aliyun-mysql to: tecent-mysql
3. 鏈?zhǔn)矫?/h2>
鏈?zhǔn)矫詈徒M合命令不一樣的地方在于:
組合命令中,每個(gè)命令之間一般是相互獨(dú)立的,
而鏈?zhǔn)矫钪?,上一個(gè)命令的執(zhí)行結(jié)果會(huì)對(duì)下一個(gè)命令造成影響。
比如:
class Stat():
def __init__(self):
self.total = 0
self.avg = 0
self.n = 0
# 模擬統(tǒng)計(jì)合計(jì)值
def sum(self, n):
self.n += n
for i in range(n):
self.total += i
return self
# 模擬求平均值
def average(self):
if self.n == 0:
self.avg = 0
else:
self.avg = self.total / self.n
return self
# 顯示分析結(jié)果
def show(self):
print("SUM: {}, and AVERAGE: {}".format(self.total, self.avg))
if __name__ == "__main__":
fire.Fire(Stat)執(zhí)行鏈?zhǔn)矫顣r(shí),可以先求和,再求平均值,最后顯示結(jié)果:
$ python main.py sum 10 average show
SUM: 45, and AVERAGE: 4.5
因?yàn)槭擎準(zhǔn)矫睿钥梢远啻螆?zhí)行:
$ python main.py sum 10 sum 10 average show
SUM: 90, and AVERAGE: 4.5
$ python main.py sum 10 sum 20 sum 30 average show
SUM: 670, and AVERAGE: 11.166666666666666
4. 復(fù)雜命令參數(shù)
上面的示例中,參數(shù)都是簡(jiǎn)單的數(shù)據(jù)類型,比如字符串,數(shù)字之類的。
最后,介紹下復(fù)雜的命令參數(shù)如何使用,所謂復(fù)雜的參數(shù),就是元組,列表,字典等等。
def hello(data):
tp = type(data).__name__
if tp == "tuple" or tp == "list":
for item in data:
print("hello: {}".format(item))
if tp == "dict":
for k, v in data.items():
print("hello: key {}, val {}".format(k, v))
if __name__ == "__main__":
fire.Fire(hello)python是弱類型語(yǔ)言,函數(shù)的參數(shù)可以是任何類型。
主要看看命令行中如何傳入復(fù)雜的類型:
$ python main.py "(aa, bb, cc)"
hello: aa
hello: bb
hello: cc
$ python main.py "[aa, bb, cc]"
hello: aa
hello: bb
hello: cc
$ python main.py "{aa: 11, bb: 22}"
hello: key aa, val 11
hello: key bb, val 22
5. 總結(jié)
Python的Fire庫(kù)是一個(gè)構(gòu)思非常巧妙的命令行接口庫(kù),各種語(yǔ)言的命令行接口我接觸過(guò)不少,還沒(méi)有在其他編程語(yǔ)言中看到過(guò)類似的庫(kù)。
Fire庫(kù)最方便的地方在于,你不用再關(guān)心命令行的參數(shù)(參數(shù)的解析一直是命令行程序中最讓人頭疼的地方),只要專注于自己要實(shí)現(xiàn)的功能。
此外,如果你已經(jīng)有一些python腳本的話,通過(guò)這個(gè)庫(kù)把它們改造成命令行程序也非常簡(jiǎn)單。
到此這篇關(guān)于Python Fire實(shí)現(xiàn)自動(dòng)生成命令行接口的文章就介紹到這了,更多相關(guān)Python Fire生成命令行接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python?正則表達(dá)式基礎(chǔ)知識(shí)點(diǎn)及實(shí)例
在本篇文章里小編給大家整理了關(guān)于Python正則表達(dá)式的一些基礎(chǔ)知識(shí)點(diǎn)以及相關(guān)用法實(shí)例內(nèi)容,需要的朋友們可以參考下。2021-12-12
Python利用multiprocessing實(shí)現(xiàn)最簡(jiǎn)單的分布式作業(yè)調(diào)度系統(tǒng)實(shí)例
這篇文章主要給大家介紹了關(guān)于Python利用multiprocessing如何實(shí)現(xiàn)最簡(jiǎn)單的分布式作業(yè)調(diào)度系統(tǒng)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-11-11
使用pylintrc配置Python代碼檢查的詳細(xì)指南
在 Python 項(xiàng)目中使用 Pylint 進(jìn)行靜態(tài)代碼檢查,可以大大提升代碼質(zhì)量與一致性,與其每次在命令行里堆一長(zhǎng)串參數(shù),不如通過(guò) pylintrc 統(tǒng)一管理配置,本文從零開(kāi)始帶大家如何使用pylintrc配置Python代碼檢查,需要的朋友可以參考下2026-03-03
Python定時(shí)發(fā)送消息的腳本:每天跟你女朋友說(shuō)晚安
今天小編就為大家分享一篇關(guān)于Python定時(shí)發(fā)送消息的腳本:每天跟你女朋友說(shuō)晚安的文章,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
python requests庫(kù)爬取豆瓣電視劇數(shù)據(jù)并保存到本地詳解
這篇文章主要介紹了python requests庫(kù)爬取豆瓣電視劇數(shù)據(jù)并保存到本地詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
Python求兩個(gè)圓的交點(diǎn)坐標(biāo)或三個(gè)圓的交點(diǎn)坐標(biāo)方法
今天小編就為大家分享一篇Python求兩個(gè)圓的交點(diǎn)坐標(biāo)或三個(gè)圓的交點(diǎn)坐標(biāo)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11
Python實(shí)現(xiàn)的簡(jiǎn)單線性回歸算法實(shí)例分析
這篇文章主要介紹了Python實(shí)現(xiàn)的簡(jiǎn)單線性回歸算法,結(jié)合實(shí)例形式分析了線性回歸算法相關(guān)原理、功能、用法與操作注意事項(xiàng),需要的朋友可以參考下2018-12-12
Python雙向循環(huán)鏈表實(shí)現(xiàn)方法分析
這篇文章主要介紹了Python雙向循環(huán)鏈表,結(jié)合實(shí)例形式分析了Python雙向鏈表的定義、遍歷、添加、刪除、搜索等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07
python針對(duì)Oracle常見(jiàn)查詢操作實(shí)例分析
這篇文章主要介紹了python針對(duì)Oracle常見(jiàn)查詢操作,結(jié)合實(shí)例形式分析了python針對(duì)Oracle常見(jiàn)的子查詢、多表查詢等相關(guān)原理、操作技巧與使用注意事項(xiàng),需要的朋友可以參考下2020-04-04

