![Python 命令行之旅:使用 argparse 实现 git 命令](http://img.jiangsulong.com/220417/0J9505a9-0.jpg)
文章插图
作者:HelloGitHub-Prodesire
前言
在前面三篇介绍 argparse 的文章中 , 我们全面了解了 argparse 的能力 , 相信不少小伙伴们都已经摩拳擦掌 , 想要打造一个属于自己的命令行工具 。
本文将以我们日常工作中最常见的 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 函数响应对应的子命令
import osimport argparsefrom git.cmd import Git??def cli(): """ git 命名程序入口 """ pass??def handle_status(git, args): """ 处理 status 命令 """ pass?def handle_add(git, args): """ 处理 add 命令 """ pass??def handle_commit(git, args): """ 处理 -m <msg> 命令 """ pass??def handle_push(git, args): """ 处理 push 命令 """ pass??if __name__ == '__main__': cli()下面我们将一步步地实现我们的 git 程序 。
实现
假定我们在 argparse-git.py[2] 文件中实现我们的 git 程序 。
构建解析器
我们需要构建一个父解析器 , 作为程序的根解析器 , 程序名称指定为 git 。然后在上面添加子解析器 , 为后续的子命令的解析做准备:
def cli(): """ git 命名程序入口 """ parser = argparse.ArgumentParser(prog='git') subparsers = parser.add_subparsers( title='These are common Git commands used in various situations', metavar='command')add_subparsers 中的 title 和 metavar 参数主要用于命令行帮助信息 , 最终的效果如下:
usage: git [-h] command ...?optional arguments: -h, --help show this help message and exit?These are common Git commands used in various situations: command ...status 子命令
我们需要在 cli 函数中添加一个用于解析 status 命令的子解析器 status_parser , 并指定其对应的处理函数为 handle_status 。
def cli(): ... # status status_parser = subparsers.add_parser( 'status', help='Show the working tree status') status_parser.set_defaults(handle=handle_status)需要说明的是 , 在
status_parser.set_defaults 函数中 , 能接收任意名称的关键字参数 , 这个参数值会存放于父解析器解析命令行参数后的变量中 。
比如 , 在本文示例程序中 , 我们为每个子解析器定义了 handle , 那么 args = parser.parse_args() 中的 args 将具有 handle 属性 , 我们传入不同的子命令 , 那么这个 handle 就是不同的响应函数 。
定义了 status 的子解析器后 , 我们再实现下 handle_status 即可实现 status 命令的响应:
推荐阅读
- 使用Streamlit从简单的Python脚本创建交互式WebApp
- 猛踩油门!令Python加速
- 使用Python检测虚假新闻
- 学习python你必须弄懂的 Python、Pycharm、Anaconda 三者的关系
- Python 图像处理 | 图像平滑之均值滤波、方框滤波、高斯滤波及中值滤波
- 教你用Python批量下载静态页面图片
- 斗记之巅峰之斗的由来,场关于斗记茶之旅的分享会分享茶会
- 用 Python 高效智能管理文件夹
- Python 100个样例代码
- 用Python从头开始实现简单遗传算法