[python] 自动生成命令行工具 - fire 简介
转自 Alan Lee
Python 中用于生成命令行接口(Command Line Interfaces, CLIs)的工具已经有一些了,例如已经成为 Python 标准库的 argparse 和第三方的 click ,这些都是很不错的工具。但是这些工具为 Python 程序生成 CLIs 的时候稍显麻烦,需要增加的地方比较多,过程稍显繁琐。今天介绍的这个工具,几乎可以不改变原始代码就可以生成 CLIs,是 Google 于 2017 年 3 月 2 日宣布在 GitHub 上开源的。

文中的三个程序文件可以在 这里 打包下载。
简介
大致的简介我在上面简单说了下,下面我引用下官方简介:
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
[python] 自动生成命令行工具 - fire 简介的更多相关文章
- python制作命令行工具——fire
python制作命令行工具--fire 前言 本篇教程的目的是希望大家可以通读完此篇之后,可以使用python制作一款符合自己需求的linux工具. 本教程使用的是google开源的python第三方 ...
- python 命令行工具 fire
简介 A library for automatically generating command line interfaces. Python Fire is a library for auto ...
- 【amad】cookiecutter -- 一个命令行工具,使用项目模版来构建项目
动机 简介 个人评分 动机 一般的框架都有脚手架工具,但是并不会让所有人满意. 简介 cookiecutter1是一个Python实现的命令行工具,可以通过项目模版来构建项目. 它的特性包括: 跨平台 ...
- [转]轻松学习Ionic (四) 修改应用图标及添加启动画面(更新官方命令行工具自动生成)
本文转自:http://blog.csdn.net/zapzqc/article/details/42237935 由于Ionic更新了命令行工具,以后修改应用图标和添加启动画面就简单了,最新方法见最 ...
- 轻松学习Ionic (四) 修改应用图标及添加启动画面(更新官方命令行工具自动生成)
由于Ionic更新了命令行工具,以后修改应用图标和添加启动画面就简单了,最新方法见最下方: 应用图标: 1.在整个项目所在文件夹下创建res文件夹,里边再分别创建两个文件夹android和io ...
- Python 命令行工具 argparse 模块使用详解
先来介绍一把最基本的用法 import argparse parser = argparse.ArgumentParser() parser.parse_args() 在执行 parse_args() ...
- Python -- Scrapy 命令行工具(command line tools)
结合scrapy 官方文档,进行学习,并整理了部分自己学习实践的内容 Scrapy是通过 scrapy 命令行工具进行控制的. 这里我们称之为 “Scrapy tool” 以用来和子命令进行区分. 对 ...
- Python 简易web日志查看工具&可改装为命令行工具
Python 简易web日志查看工具&可改装为命令行工具 效果图 原理 利用python的paramiko库模拟ssh登录操作,并执行tail命令 所需库 flask.paramiko.gev ...
- MSSQL-Scripter,一个新的生成T-SQL脚本的SQL Server命令行工具
这里向大家介绍一个新的生成T-SQL脚本的SQL Server命令行工具:mssql-scripter.它支持在SQL Server.Azure SQL DB以及Azure SQL DW中为数据库生成 ...
随机推荐
- SuperSocket自定义server、session、command、分隔符,WinForm服务端
文件下载地址https://files.cnblogs.com/files/xixixing/WindowsFormsApp.zip key和body以及body中参数间,默认通过空格分隔.修改构造函 ...
- BZOJ 3931: [CQOI2015]网络吞吐量 Dijkstra+最大流
这个没啥难的. 只保留可以转移最短路的边,然后拆点跑一个最大流即可. #include <bits/stdc++.h> #define N 1004 #define M 250004 #d ...
- 洛谷P2135 方块消除
洛谷题目链接 动态规划(真毒瘤!) 变量声明: $val[i]$:表示第$i$块颜色 $num[i]$:表示第$i$块颜色数量 $sum[i]$:表示$num$的前缀和 我们设计状态$f[l][r][ ...
- 洛谷 U5122 T2-power of 2(费马小定理)
U5122 T2-power of 2 题目提供者胡昊 题目描述 是一个十分特殊的式子. 例如: n=0时 =2 然而,太大了 所以,我们让对10007 取模 输入输出格式 输入格式: n 输出格式: ...
- 【线性代数】3-5:独立性,基和维度(Independence,Basis and Dimension)
title: [线性代数]3-5:独立性,基和维度(Independence,Basis and Dimension) categories: Mathematic Linear Algebra ke ...
- 【CUDA 基础】4.5 使用统一内存的向量加法
title: [CUDA 基础]4.5 使用统一内存的向量加法 categories: - CUDA - Freshman tags: - 统一内存 - Uniform Memory toc: tru ...
- msbuild不是内部或外部命令
首先这个问题纠结了很久,在网上找了查阅了很多博客,大多在介绍介绍批处理为何物,但是就是没有明确的解决方案. 如果想具体了解msbuild是何物,自己查找资料把. 好吧,下面介绍下正确的解决方案. 很简 ...
- Linux 常用命令安装
系统版本: Centos-7-x86_64-minimal 1. 网络相关 1.1 MTR 跟踪路由,还可以测试丢包率.网络延迟 yum -y install mtr 2. 文件相关 2.1 sz ...
- 之前有面试到两个日期的大小比较方式,现在整理一下几种方法。 例子: String beginTime=new String("2017-06-09 10:22:22"); String endTime=new String("2017-05-08 11:22:22"); 1 直接用Date自带方法before()和after()比较 SimpleDateFormat d
各种数据类型(日期/时间.integer.floating point和numeric)转换成格式化的字符串以及反过来从格式化的字符串转换成指定的数据类型.下面列出了这些函数,它们都遵循一个公共的调用 ...
- 【Webscraper】不懂编程也能爬虫
一.配置环境 在浏览器中安装web scraper插件. 所有安装包下载链接: https://pan.baidu.com/s/1CfAWf0wMO6WqicoUgdYgkg 提取码: nn2e 安装 ...