【Python】自動生成命令列工具
Python 中用於生成命令列介面(Command Line Interfaces, CLIs)的工具已經有一些了,例如已經成為 Python 標準庫的 argparse 和第三方的 click ,這些都是很不錯的工具。但是這些工具為 Python 程式生成 CLIs 的時候稍顯麻煩,需要增加的地方比較多,過程稍顯繁瑣。今天介紹的這個工具,幾乎可以不改變原始程式碼就可以生成 CLIs,是 Google 於 今年(2017 年)3 月 2 日宣佈在 GitHub 上開源的。
文中的三個程式檔案可以在 這裡 打包下載。
更新
這裡我會列出對本文的更新。
- 2017 年 10 月 18 日:優化排版,與其他博文保持風格統一。
簡介
大致的簡介我在上面簡單說了下,下面我引用下官方簡介:
Python Fire is a library for creating command line interfaces (CLIs) from absolutely any Python object.
- Python Fire is a simple way to create a CLI in Python.
- Python Fire is a helpful tool for developing and debugging Python code.
- Python Fire helps with exploring existing code or turning other people’s code into a CLI.
- Python Fire makes transitioning between Bash and Python easier.
- Python Fire makes using a Python REPL easier by setting up the REPL with the modules and variables you’ll need already imported and created.
可以看出來,Fire 不僅僅是一個生成 CLIs 的工具,而且還可以除錯 Python 程式,互動式的使用 Fire 。
安裝
在命令列中執行 pip install fire
用法
使用 fire
生成 CLIs 的基本用法就是使用 fire.Fire()
,可以傳入任意引數,用官方的說法就是 any Python object 。下面我舉三個例子簡單的說明一下用法,更多的用法大家可以參考 The Python Fire Guide 和 Using a Fire CLI 。
下面的例子均是以計算時間差(兩個日期之間相差的天數)的程式為例。
單個函式
檔案 test-fire.py
import fire
import datetime
def cal_days(date_str1, date_str2):
'''計算兩個日期之間的天數'''
date_str1 = str(date_str1)
date_str2 = str(date_str2)
d1 = datetime.datetime.strptime(date_str1, '%Y%m%d')
d2 = datetime.datetime.strptime(date_str2, '%Y%m%d')
delta = d1 - d2
return delta.days
if __name__ == '__main__':
fire.Fire(cal_days)
這個程式中只有一個函式 cal_days
,最後使用 fire.Fire(cal_days)
來生成 CLIs。
我們可以先用下面的語句檢視幫助資訊:
$ python test-fire.py
Fire trace:
1. Initial component
2. ('The function received no value for the required argument:', 'date_str1')
Type: function
String form: <function cal_days at 0x000002F0099B7F28>
File: d:\masterfiles\notebook\test-fire.py
Line: 4
Docstring: 計算兩個日期之間的天數
Usage: test-fire.py DATE_STR1 DATE_STR2
test-fire.py --date-str1 DATE_STR1 --date-str2 DATE_STR2
我們可以看到傳給 fire.Fire()
的引數型別(function
)、檔案路徑、文件字串、引數用法等資訊。
現在我們試著計算一下 2017 年 4 月 21 號和 2017 年 4 月 1 號差了多少天:
$ python test-fire.py 20170421 20170401
20
當然,你也可以使用 python test-fire.py --date-str1 20170421 --date-str2 20170401
。
此外,對於這種單個函式的情況,程式的最後一行 fire.Fire(cal_days)
可以改為 fire.Fire()
,結果完全一樣,fire.Fire()
會預設使用 cal_days()
函式。
多個函式
檔案 test-fire-2func.py
import fire
import datetime
def cal_days(date_str1, date_str2):
'''計算兩個日期之間的天數'''
date_str1 = str(date_str1)
date_str2 = str(date_str2)
d1 = datetime.datetime.strptime(date_str1, '%Y%m%d')
d2 = datetime.datetime.strptime(date_str2, '%Y%m%d')
delta = d1 - d2
return delta.days
def days2today(date_str):
'''計算某天距離今天的天數'''
date_str = str(date_str)
d = datetime.datetime.strptime(date_str, '%Y%m%d')
delta = datetime.datetime.now() - d
return delta.days
if __name__ == '__main__':
fire.Fire()
這個程式比 test-fire.py
多了一個函式,但是結尾處仍然使用 fire.Fire()
來生成 CLIs。我們先不輸任何引數:
$ python test-fire-2func.py 20170401
Fire trace:
1. Initial component
2. ('Cannot find target in dict', '20170401', {'__name__': '__main__', 'datetime': <module 'datetime' from 'C:\\Users\\secsi\\Anaconda3\\lib\\datetime.py'>, 'cal_days': <function cal_days at 0x0000027A855E7F28>, 'days2today': <function days2today at 0x0000027A86EC6B70>, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000027A85655A90>, '__file__': 'test-fire-2func.py', '__cached__': None, 'fire': <module 'fire' from 'C:\\Users\\secsi\\Anaconda3\\lib\\site-packages\\fire\\__init__.py'>, '__package__': None, '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__spec__': None})
Type: dict
String form: {'__name__': '__main__', 'datetime': <module 'datetime' from 'C:\\Users\\secsi\\Anaconda3\\lib\\d <...> kage__': None, '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__spec__': None}
Length: 12
Usage: test-fire-2func.py
test-fire-2func.py datetime
test-fire-2func.py cal-days
test-fire-2func.py days2today
test-fire-2func.py fire
程式中有個兩個函式,而我們執行 python test-fire-2func.py 20170401
的時候卻沒有指定使用哪個函式,所以會報錯。
正確的寫法應該是這樣的:
$ python test-fire-2func.py days2today 20170401
21
$ python test-fire-2func.py cal_days 20170422 20170401
21
也就是說在後面跟上要使用的函式名。
物件(類)
Fire
既然能夠 fire 任何 Python 物件,那麼給 fire.Fire()
傳一個類也是完全可以的。下面是一個例子:
檔案 test-fire-class.py
import fire
import datetime
class DateStr(object):
def cal_days(self, date_str1, date_str2):
'''計算兩個日期之間的天數'''
date_str1 = str(date_str1)
date_str2 = str(date_str2)
d1 = datetime.datetime.strptime(date_str1, '%Y%m%d')
d2 = datetime.datetime.strptime(date_str2, '%Y%m%d')
delta = d1 - d2
return delta.days
def days2today(self, date_str):
'''計算某天距離今天的天數'''
date_str = str(date_str)
d = datetime.datetime.strptime(date_str, '%Y%m%d')
delta = datetime.datetime.now() - d
return delta.days
if __name__ == '__main__':
fire.Fire(DateStr)
這裡我定義了一個 DateStr
類,有兩個類方法 cal_days
和 days2today
,那麼我只需 fire.Fire(DateStr)
就可以呼叫這兩個類方法。
$ python test-fire-class.py days2today 20170401
21
$ python test-fire-class.py cal-days 20170422 20170401
21
還有幾點
fire
預設使用-
作為引數分隔符,所以如果你要在命令列傳入類似2017-04-22
的引數時,那麼程式接收到的引數就肯定不是2017-04-22
了,你需要使用--separator
來改變分隔符,參考 Changing the Separatorfire
會自動區分你在命令列傳入的引數的型別,例如20170422
會自動識別成int
,hello
會自動識別成str
,'(1,2)'
會自動識別成tuple
,'{"name": "Alan Lee"}'
會自動識別成dict
。但是你如果想要傳入一個字串型別的20170422
怎麼辦?那就需要這樣寫:'"20170422"'
或者"'20170422'"
或者\"20170422\"
,總之呢,就是加一個轉義,因為命令列預設會吃掉你的引號。參考 Argument Parsing
END
相關推薦
【Python】自動生成命令列工具
Python 中用於生成命令列介面(Command Line Interfaces, CLIs)的工具已經有一些了,例如已經成為 Python 標準庫的 argparse 和第三方的 click ,這些都是很不錯的工具。但是這些工具為 Python 程式生成 C
【Python】 文件目錄比較工具filecmp和difflib
返回 我沒 直接 既然 hash this 上下 direct 不同 在一些運維場景中,常常需要比較兩個環境中的應用目錄結構(是否有文件/目錄層面上的增刪)以及比較兩個環境中同名文件內容的不同(即文件層面上的改)。Python自帶了兩個內建模塊可以很好地完成這個工作,f
【Python】uuid生成唯一ID
uuid是128位的全域性唯一識別符號(univeral unique identifier),通常用一個32位的字串的形式來表現。有時也稱guid(global unique identifier)。python中自帶了uuid模組來進行uuid的生成和管理工作。(pyth
【譯】自動生成整型序列
目錄:https://www.cnblogs.com/liqingwen/p/10261436.html 當需要一系列整型值時,可以使用某種迴圈手動建立,或者可以使用 Enumerable.Range 方法。以下為程式碼說明: var oneT
【Python】如何生成柯西分佈隨機數
Python中生成標準柯西分佈的函式是:numpy.random.standard_cauchy(size),我就在想,能否生成一個非標準的柯西隨機數呢?那麼面臨幾個問題:(1)標準柯西隨機數和非標準可惜隨機數之間有沒有之間轉化關係?(沒有)(2)柯西隨機數是怎麼生成的?(3
【PE】Windows平臺命令列中使用vcvarsall.bat配置編譯環境
###Date: 2017/9/20 一、關於命令列編譯環境的配置方法 對於VS2015,%VS140COMNTOOLS%/VC下就有vcvarsall.bat,用於生成命令列編譯環境。 對於V
【Hibernate】自動生成資料庫表
雖說整體上對SSH有一定的把控使用能力,但還是見微知著,點滴積累。Hibernate本意是冬眠,很好的封裝了JDBC和資料庫互動,實現了物件的持久化操作。所以也可以理解物件的持久化其實就是“冬眠”
【Java】Java的命令列引數
說明 命令列引數就是main方法裡面的引數String[] args,args只是資料型別的一個名稱,可任意命名 當你在Java命令列後面帶上引數,JVM就直接把引數存放到了main方法中的引數String數組裡 格式 Java中的命令列引數格式: public stat
生成命令列介面--google開源的fire使用體驗【python-fire】
在python中,命令列介面常用的argparse 和click,但是相對於python-fire 來說靈活度太缺了,fire可以直接將python中的函式,以命令列顯示. 簡單的介紹幾個例子: #!/usr/bin/env python # -*- coding: utf-8
【Python】【pytest】【常用命令列選項】
https://www.cnblogs.com/cnkemi/p/9989019.html http://www.cnblogs.com/cnkemi/p/10002788.html pytest 常用命令列選項(一) pytest有豐富的命令列選項,以滿足不同的需要,下面對常用的命令列選項作下簡單介
【Mac】Mac OS X 安裝GNU命令列工具
macos的很多使用者都是做it相關的人,類unix系統帶來了很多方面,尤其是經常和linux打交道的人。 但是作為經常使用linux 命令列的人發現macos中的命令列工具很多都是bsd工具,跟linux下得使用方式開始差距挺大的,那麼怎麼安裝GNU命令
輕鬆學習Ionic (四) 修改應用圖示及新增啟動畫面(更新官方命令列工具自動生成)
<platform name="android"> <icon src="res/android/ldpi.png" density="ldpi" /> <icon src="res/android/mdpi.png" de
【FFMpeg視訊開發與應用基礎】一、使用FFmpeg命令列工具和批處理指令碼進行簡單的音視訊檔案編輯
《FFMpeg視訊開發與應用基礎——使用FFMpeg工具與SDK》視訊教程已經在“CSDN學院”上線,視訊中包含了從0開始逐行程式碼實現FFMpeg視訊開發的過程,歡迎觀看!連結地址:FFMpeg視訊開發與應用基礎——使用FFMpeg工具與SDK
全網最詳細的一個超級好用的命令列工具【Cmder】的優點有哪些?
不多說,直接上乾貨! 1、把conemu,msysgit和clink打包在一起,讓你無需配置就能使用一個真正乾淨的Linux終端!甚至還附帶了漂亮的monokai配色主題。 2、選中右擊直接可以實現複製功能 3、主控臺文字自動放大縮小功能,按下Ctrl+滑鼠滾輪就可以
全網最詳細的一個超級好用的命令列工具【Cmder】的下載與安裝(圖文詳解)
不多說,直接上乾貨! 下載的時候,有兩個版本,分別是mini與full版;唯一的差別在於有沒有內建msysgit工具,這是Git for Windows的標準配備;全安裝版 cmder 自帶了 msysgit, 壓縮包 23M, 除了 git 本身這個命令之外, 裡面
全網最詳細的一個超級好用的命令列工具【Cmder】的安裝之後的一些配置(圖文詳解)
不多說,直接上乾貨! 1、修改命令提示符λ為$ 首先,我們看到 進入解壓後的cmder的目錄,進入vendor,開啟init.bat檔案。 修改第15行的程式碼 @prompt $E[1;32;40m$P$S
全網最詳細的一個超級好用的命令列工具【Cmder】是什麼?
不多說,直接上乾貨! Cmder是什麼? 一款Windows環境下非常簡潔美觀易用的cmd替代者,它支援了大部分的Linux命令。支援ssh連線linux,使用起來非常方便。比起cmd、powershell、conEmu,其介面美觀簡潔,功能強大。
【ffmpeg】視訊編解碼之ffmpeg命令列工具的常用命令彙總
H264視訊轉ts視訊流 ffmpeg -i test.h264 -vcodec copy -f mpegts test.ts H264視訊轉mp4 ffmpeg -i test.h264 -vcodec copy -f mp4 test.mp4 ts視訊轉mp4 ffmpeg
Wireshark命令列工具tshark使用小記 【轉】
1、目的 寫這篇部落格的目的主要是為了方便查閱,使用wireshark可以分析資料包,可以通過編輯過濾表示式來達到對資料的分析;但我的需求是,怎麼樣把Data部分匯出來,因為後續的工作主要針對資料包的Data部分,主要是對本地儲存的.pcap檔案進行解析。這
【工具】輕量級 linux 命令列發郵件工具--SendEmail
An Email Program for Sending SMTP Mail from a Command Line About SendEmail SendEmail is a lightweight, command line SMTP email clien