Python命令行之旅:使用argparse实现git命令
前言
本文將以我們日常工作中最常見的git命令為例,講解如何使用argparse庫來實現一個真正可用的命令行程序。
- 本文默認使用 Python 3 作為解釋器進行講解。
- 若你仍在使用 Python 2,請注意兩者之間語法和庫的使用差異哦~
git常用命令
大家不妨回憶一下,平時最常使用git子命令都有哪些?
當你寫好一段代碼或增刪一些文件后,會用如下命令查看文件狀態:
git status確認文件狀態后,會用如下命令將的一個或多個文件(夾)添加到暫存區:
git add [pathspec [pathspec ...]]然后使用如下命令提交信息:
git commit -m "your commit message"最后使用如下命令將提交推送到遠程倉庫:
git push我們將使用argparse和gitpython庫來實現這4個子命令。
關于gitpython
gitpython [1]是一個和git倉庫交互的Python第三方庫。我們將借用它的能力來實現真正的git邏輯。
安裝:
pip install gitpython思考
在實現前,我們不妨礙先思考下會用到argparse的某些功能?整個程序的結構是怎樣的?
argparse
-
要實現子命令,那么之前介紹到的嵌套解析器必不可少
-
當用戶鍵入子命令時,子命令所對應的子解析器需要作出響應,那么需要用到子解析器的set_defaults功能
-
針對git add [pathspec [pathspec …]],我們需要實現位置參數,而且數量是任意個
-
針對git commit --message msg或git commit -m msg,我們需要實現選項參數,并且可以長選項,又可短選項
程序結構
-
命令行程序需要一個cli函數來作為統一的入口,它負責合并解析器,并解析命令行參數
-
我們還需要四個handle_xxx函數響應對應的子命令
則基本結構如下:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' import os import argparse from git.cmd import Gitdef cli():"""git 命名程序入口"""passdef handle_status(git, args):"""處理 status 命令"""passdef handle_add(git, args):"""處理 add 命令"""passdef handle_commit(git, args):"""處理 -m <msg> 命令"""passdef handle_push(git, args):"""處理 push 命令"""passif __name__ == '__main__':cli()下面我們將一步步地實現我們的git程序。
實現
預先我們在argparse-git.py [2]文件中實現我們的git程序。
構建解析器
我們需要整合一個父解析器,作為程序的根解析器,程序名稱指定為git。然后在上面添加子解析器,為后續的子命令的解析做準備:
狀態子命令
我們需要在cli函數中添加一個用于解析status命令的子解析器status_parser,并指定其對應的處理函數為handle_status。
需要說明的是,在status_parser.set_defaults函數中,能接收任意名稱的關鍵字參數,這個參數值會存放于父解析器解析命令行參數后的變量中。
例如,在此示例程序中,我們為每個子解析器定義了handle,那么args = parser.parse_args()中的args將具有handle屬性,我們可以引用不同的子命令,那么這個handle就是不同的響應函數。
定義了status的子解析器后,我們再實現下handle_status即可實現status命令的響應:
def handle_status(git, args):"""處理 status 命令"""cmd = ['git', 'status']output = git.execute(cmd)print(output)不尖銳出,我們最后調用了真正的git status來實現,并打印了輸出。
可能你會對handle_status的函數簽名感到困惑,的這里git狀語從句:args的英文怎么傳入的呢?這其實是由我們自己控制的,將在本文最后講解。
添加子命令
同樣,我們需要在cli函數中添加一個用于解析add命令的子解析器add_parser,并指定其對應的處理函數為handle_add。
額外要做的是,要在子解析器add_parser上添加一個pathspec位置參數,且其數量是任意的:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def cli():...# addadd_parser = subparsers.add_parser('add',help='Add file contents to the index')add_parser.add_argument('pathspec',help='Files to add content from',nargs='*')add_parser.set_defaults(handle=handle_add)然后,就是實現handle_add函數,我們需要用到表示文件路徑的args.pathspec:
def handle_add(git, args):"""處理 add 命令"""cmd = ['git', 'add'] + args.pathspecoutput = git.execute(cmd)print(output)提交子命令
同樣,我們需要在cli函數中添加一個用于解析commit命令的子解析器commit_parser,并指定其對應的處理函數為handle_commit。
額外要做的是,要在子解析器commit_parser上添加一個-m/ --message選項參數,且要求必填:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def cli():...# commitcommit_parser = subparsers.add_parser('commit',help='Record changes to the repository')commit_parser.add_argument('--message', '-m',help='Use the given <msg> as the commit message',metavar='msg',required=True)commit_parser.set_defaults(handle=handle_commit)然后,就是實現handle_commit函數,我們需要用到表示提交信息的args.message:
def handle_commit(git, args):"""處理 -m <msg> 命令"""cmd = ['git', 'commit', '-m', args.message]output = git.execute(cmd)print(output)推子命令
同樣,我們需要在cli函數中添加一個用于解析push命令的子解析器push_parser,并指定其對應的處理函數為handle_push。
它同status子命令的實現方式一致:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def cli():...# pushpush_parser = subparsers.add_parser('push',help='Update remote refs along with associated objects')push_parser.set_defaults(handle=handle_push)然后,就是實現handle_push函數,和handle_status類似:
def handle_push(git, args):cmd = ['git', 'push']output = git.execute(cmd)print(output)解析參數
在定義完父子解析器,并添加參數后,我們就需要對參數做解析,從而工作也是實現在cli函數中:
-
通過git.cmd.Git實例化出git對象,用來和git倉庫互動
-
通過parser.parse_args()解析命令行
-
通過hasattr(args, ‘handle’)判斷是否輸入了子命令。
-
由于每個子解析器都定義了handle,那么如果當用戶在命令行不輸入任何命令時,args就沒有handle屬性,那么我們就輸出幫助信息
-
如果用戶輸入了子命令,那么就調用args.handle,引用git和args對象,進行處理對應命令
-
至此,我們就實現了一個簡單的git命令行,使用python argparse-git.py -h查看幫助如下:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' usage: git [-h] command ...optional arguments:-h, --help show this help message and exitThese are common Git commands used in various situations:commandstatus Show the working tree statusadd Add file contents to the indexcommit Record changes to the repositorypush Update remote refs along with associated objects然后我們就可以愉快地使用親手打造的git程序啦!
小結
本文簡單介紹了日常工作中常用的git命令,然后提出實現它的思路,最終一步步使用argparse和gitpython實現了git程序。是不是很有成就感呢?
你是否想過,argparse的四步曲雖然理解簡單,但略微麻煩。有沒有更簡單的方式?如果我很熟悉命令行幫助語法,我能不能寫個幫助字符串就把所有的命令行元信息給定義出來?然后就直接輕松輕松地地獲取解析后的參數信息呢?
總結
以上是生活随笔為你收集整理的Python命令行之旅:使用argparse实现git命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 30段极简Python代码:这些小技巧你
- 下一篇: Python 常见优化技巧,让你的程序溜