python命令行解析工具
在使用python的過程中,會經常遇到一些命令要在命令行中操作,比如pip
和python
,或者是一些庫如jupyter-themes庫(用於修改jupyter的頁面樣式)中的jt命令(比如用jt -t grade3
這樣的命令套用grade3樣式模板)
python --version
或python -h
。(後面--
和-
是命令行中接參數的兩種方法,和python中的函數接參數一樣)因為python和pip在前面的文章中已經講過,這裡拿jt來舉例子jt -t grade3
這條命令其實是調用了jt.exe文件,並把t參數賦值為grade3傳入運行。而這個.exe文件其實是.py文件打包而成的。所以說它的過程是這樣的:
- 寫好一個jt.py文件,但是運行這個文件需要外部輸入參數
- jt.py文件裡面要定義一些方法來接受cmd中輸入的參數
- 最後實現可以運行
python jt.py -t grade3
- 再將jt.py文件打包成exe文件
- 最後就可以運行
jt -t grade3
其中第二步————接受cmd中輸入的參數,需要用到的就是命令行解析工具。
python中有很多命令行解析庫,主要有如下幾種- sys.argv
- argparse庫
- click庫
- fire庫(這是一個神器)
- 總結
下面我們分別進行講解
sys.argv
可以把sys.argv理解成一個list
- 其中第一個元素是代碼所在的module,比如代碼是在cmd.py文件夾下編輯,在命令行中運行
python cmd.py
,此時sys.argv[0]
就是cmd.py - 後面的元素是我們在命令行中給它加入的參數
我們看一下下面例子
1.sys.argv[0]在cmd.py文件中輸入下面內容import sysna = sys.argv[0]nprint(a)n
在cmd.py所在文件夾中打開cmd(本文之後所有在cmd中輸入都指的是在這個文件夾下的cmd),輸入
python cmd.pyn
返回 cmd.py
如果我們只關注我們輸入的參數,則可以不關注sys.argv[0]
2.sys.argv[i] i = 1,2,3…
下面我們來看一下如何將命令行中的參數傳入python腳本中運行
(1)最簡單是使用在cmd.py文件中輸入import sysna = sys.argv[1]nprint(a)n
在cmd中輸入
python cmd.py 2n
返回2
(2)支持切片一
在cmd.py文件中輸入import sysna = sys.argv[1:]nprint(a)n
在cmd中輸入
python cmd.py 2 3 4n
返回[2, 3, 4]
(3)支持切片二
在cmd.py文件中輸入import sysna = sys.argv[1:3]nfor i in a:n print(i)n
在cmd中輸入
python cmd.py 2 3 4n
返回2 3
用sys模塊只支持一些簡單的傳入,如果要複雜一些,設定參數名稱,則要使用下面的庫
argparse庫
argparse是python內置庫,是最常用的命令行解析庫,官網的教程非常詳細,是從最簡單的命令開始,一步一步增加可以實現的功能。我如果寫也是這麼寫,所以不再進行過多重複,只是簡單展示一個實例。
在cmd.py文件中輸入
import argparse # 1nparser = argparse.ArgumentParser() #2nnparser.add_argument(text, help = print some text) # 3nparser.add_argument(-v,--value, nargs = 2, type = int, help = the sum of 2 int)nnargs = parser.parse_args() # 4nn# 輸出兩個部分nprint(args.text)nnif args.value:n print(args.value[0]+args.value[1])n
其中標號1 2 3 4是argparse庫的最基本四個步驟
- 導入庫
- 初始化解析器
- 增加參數
- 解析參數,讓args可以調用
下面我們在命令行中調用
(1)只調用text參數
python cmd.py whatn
返回 what
(2)兩個參數都調用
python cmd.py -v 2 3 whatn
返回 what 5
-v
是--value
參數的簡寫形式,在cmd中調用參數直接用空格分隔,兩個參數之間也用空格分隔開
(3)用value完整參數
python cmd.py what --value 5 3n
返回 what 8
(4)調用命令的幫助文檔
python cmd.py -hn
返回如下內容
usage: cmd.py [-h] [-v VALUE VALUE] textnnpositional arguments:n text print some textnnoptional arguments:n -h, --help show this help message and exitn -v VALUE VALUE, --value VALUE VALUEn the sum of 2 intn
-h
或者--help
不需要在.py文件中定義即可使用- 這裡可以看到命令的用法
cmd.py [-h] [-v VALUE VALUE] text
表明了輸入參數的方法和順序等 - 還把每個參數列在下面,把我們在cmd.py文件中,每個參數的help參數中的內容列印了出來
click
這個庫的語法和argparse差不太多,只是改成裝飾器形式,官網的教程個人認為不是十分清楚,沒有把完整的代碼寫出來,網上的博客也很多都是直接複製官網的代碼,所以下面的例子有比較大的借鑒意義。但是如果想深入研究還是要看官網的說明的
(1)一個簡單的實例
cmd.py文件中寫入import clicknn@click.command() # 讓它成為一個命令行工具n@click.argument(name) # 將name參數傳入ndef newprint(name):n click.echo(my name is + name) # 用echo代替print,有一些比較細節的好處,當成print就好nnnewprint() # 這裡調用的時候就不用接參數了n
在cmd中輸入
python cmd.py bobn
(2)多個函數
import clicknn# 定義第一個函數n@click.command() n@click.argument(name)ndef newprint(name):n click.echo(my name is + name)nn# 定義第二個函數n@click.command()n@click.argument(a, type = int)n@click.argument(b, type = int)ndef newadd(a,b):n click.echo(a+b)nn# 將兩個函數結合n@click.group() # 用於整合多個函數ndef cli():n passnncli.add_command(newprint)ncli.add_command(newadd)nncli()n
在cmd中輸入
python cmd.py newadd 2 3n
返回5
輸入
python cmd.py newprint bobn
返回my name is bob
下面這個庫,個人認為結合了上面的所有優點,而且一切都更簡潔清晰,簡直是神器
fire庫
這是一個命令行解析的神器,沒有前面解析庫中那麼複雜的過程,它可以實現在cmd中直接調用py文件中的函數、變數、類、實例等等,更符合我們的思維習慣
這個庫也有非常簡明易懂的官方教程(1)將py文件中的所有函數都導入
在cmd.py文件中輸入import firenndef newprint(text):n print(my +text)nndef newadd(a,b):n return a + bnnfire.Fire() # 只要這一條命令n
在cmd中輸入
python cmd.py newprint notebookn
返回 my notebook
輸入
python cmd.py newadd 2 3n
返回5
輸入(可以指定函數的參數)
python cmd.py newadd --a 2 --b 3n
返回5
其實如果py文件中定義有變數,這樣也會把變數導入,在命令行中輸入
python cmd.py 變數名n
即可查看變數內容
(2)導入指定函數
將cmd.py文件中的fire.Fire()
換成fire.Fire(newadd)
,這樣就只能使用newadd函數,而且不需要寫newadd函數名,直接接參數即可,調用如下python cmd.py --a 2 --b 3n
(其實上面的這個用法和其他庫的用法是一樣的,只是解析時代碼更簡單)
若要傳入多個函數而不是全部函數,則fire.Fire()
換成
fire.Fire({n newadd: newadd,n newprint: newprint,n})n
其實我們一般也只要導入一個函數即可,其他函數均由這個函數調用
(3)導入類或實例
其實也可以在py文件中定義類,將類傳入,或者再定義出一個實例,將實例傳入,分別把fire.Fire()
換為
fire.Fire(Myclass)nfire.Fire(myinstance)n
而實例中的比如newadd方法,則和上面調用函數完全一樣來調用即可
python cmd.py newadd 2 3n
還可以傳入實例創建時的初始參數,我們來看下面一個例子
import firennclass Myclass:nn def __init__(self, name):n self.name = namenn def nameprint(self, anything):n print(anything + , my name is + self.name)nnfire.Fire(Myclass)n
在cmd中輸入
python cmd.py nameprint Yes --name bobn
輸出Yes, my name is bob
總結
- argv和argparse庫調用的函數其實都寫在py文件里,在命令行中只是傳入函數要調用的參數
- click用裝飾器既實現了在py函數中調用函數、命令行輸入參數的形式;而且可以在命令行中指定調用哪個函數和參數
- fire庫也是二者都可以,這個庫的代碼設計更加簡潔
專欄信息
專欄主頁:Data Analysis
專欄目錄:目錄
版本說明:軟體及包版本說明
推薦閱讀:
※Python 所謂的「閉包」是不是本著故意把人搞暈的態度發明出來的?
※使用了Gunicorn或者uWSGI,為什麼還需要Nginx?
※解構國內首個函數計算(從概念、入門再到實戰)
※50?python爬?代碼, 帶你正確打開知乎新世界!
※python anaconda 怎麼安裝?