Google 开源的 Python 命令行库:深入 fire(一)

作者:HelloGitHub-Prodesire
HelloGitHub 的《讲解开源项目》系列,项目地址:https://github.com/HelloGitHub-Team/Article
一、前言
在第一篇“初探 fire”的文章中,我们初步掌握了使用 fire 的简单步骤,了解了它 Pythonic 的用法。
今天我们将深入了解 fire 的子命令、嵌套命令和属性访问功能。
本系列文章默认使用 Python 3 作为解释器进行讲解。
若你仍在使用 Python 2,请注意两者之间语法和库的使用差异哦~
二、功能
2.1 子命令
使用 fire 实现子命令有多种方式:
2.1.1 定义若干函数,使用 fire.Fire()
实现子命令最简单的方式就是定义若干个函数,每个函数名隐式就是子命令名称,然后调用 fire.Fire() 变将当前模块所有的函数解析为对应的子命令的处理函数。
import fire
def add(x, y):
return x + y
def multiply(x, y):
return x * y
if __name__ == '__main__':
fire.Fire()
然后我们就可以在命令行中这么调用:
$ python example.py add 10 20
30
$ python example.py multiply 10 20
200
关于如何识别参数类型,比如上述 add 10 20 中 10 和 20 是作为数字而非字符串,我们会在下篇文章的参数解析章节中进行讲解。
2.1.2 定义若干函数,使用 fire.Fire()
在 2.1.1 的版本中,会把所有函数都当做是子命令。有时我们可能只想把部分函数当做子命令,或者是希望子命令名称和函数名称不一样。这个时候我们就可以通过字典对象显式地告诉 fire。
字典对象的形式为 {'子命令名称': 函数},比如前面的示例中,我们希望最终的子命令为 add 和 mul,那么就可以这么写:
fire.Fire({
'add': add,
'mul': multiply,
})
然后我们就可以在命令行中这么调用:
$ python example.py add 10 20
30
$ python example.py mul 10 20
200
2.1.3 定义类和方法,使用 fire.Fire()
定义类和方法的这种方式我们在上一篇文章中介绍过,它和定义函数的方式基本相同,只不过是用类的方式来组织。
然后将类实例化,并把实例化的对象多为 fire.Fire 的入参:
import fire
class Calculator(object):
def add(self, x, y):
return x + y
def multiply(self, x, y):
return x * y
if __name__ == '__main__':
calculator = Calculator()
fire.Fire(calculator)
2.1.4 定义类和方法,使用 fire.Fire()
和 2.1.3 中的唯一不同点是把类而非实例对象作为 fire.Fire 的入参:
fire.Fire(Calculator)
传递类和实例对象的基本作用是一样的,但传递类还有一个额外的特性:如果构造函数中定义了参数,那么这些参数都会作为整个命令行程序的选项参数。
import fire
class BrokenCalculator(object):
def __init__(self, offset=1):
self._offset = offset
def add(self, x, y):
return x + y + self._offset
def multiply(self, x, y):
return x * y + self._offset
if __name__ == '__main__':
fire.Fire(BrokenCalculator)
查看帮助命令有:
$ python example.py --help
INFO: Showing help with the command 'example.py -- --help'.
NAME
example.py
SYNOPSIS
example.py <flags>
FLAGS
--offset=OFFSET
由此可见构造函数 BrokenCalculator.__init__(self, offset=1) 中的 offset 自动转换为了命令行中的全局选项参数 --offset,且默认值为 1。
我们可以在命令行中这么调用:
$ python example.py add 10 20
31
$ python example.py multiply 10 20
201
$ python example.py add 10 20 --offset=0
30
$ python example.py multiply 10 20 --offset=0
200
2.2 命令组/嵌套命令
想要实现嵌套命令,可将多个类组织起来,示例如下:
class IngestionStage(object):
def run(self):
return 'Ingesting! Nom nom nom...'
class DigestionStage(object):
def run(self, volume=1):
return ' '.join(['Burp!'] * volume)
def status(self):
return 'Satiated.'
class Pipeline(object):
def __init__(self):
self.ingestion = IngestionStage()
self.digestion = DigestionStage()
def run(self):
self.ingestion.run()
self.digestion.run()
if __name__ == '__main__':
fire.Fire(Pipeline)
在上面的示例中:
IngestionStage实现了子命令runDigestionStage实现了子命令run和statusPipeline的构造函数中将IngestionStage实例化为ingestion,将DigestionStage实例化为digestion,就将这两个放到一个命令组中,因而支持了:ingestion rundigestion rundigestion status
Pipeline实现了子命令run
因此整个命令行程序支持如下命令:
runingestion rundigestion rundigestion status
然后我们就可以在命令行中这么调用:
$ python example.py run
Ingesting! Nom nom nom...
Burp!
$ python example.py ingestion run
Ingesting! Nom nom nom...
$ python example.py digestion run
Burp!
$ python example.py digestion status
Satiated.
2.3 属性访问
属性访问 是 fire 相对于其他命令行库来说一个比较独特的功能。所谓访问属性是获取预置的属性所对应的值。
举个例子,在命令行中指定 --code 来告知程序要查询的程序编码,然后希望通过 zipcode 属性返回邮编,通过 city 属性返回城市名。那么属性可实现为实例成员属性:
import fire
cities = {
'hz': (310000, '杭州'),
'bj': (100000, '北京'),
}
class City(object):
def __init__(self, code):
info = cities.get(code)
self.zipcode = info[0] if info else None
self.city = info[1] if info else None
if __name__ == '__main__':
fire.Fire(City)
使用方式如下:
$ python example.py --code bj zipcode
100000
$ python example.py --code hz city
杭州
三、小结
使用 fire 实现子命令和嵌套命令相对于其他命令行库来说都更加简单清晰,不仅如此,fire 还提供了属性访问这种较为独特的能力。
在下篇文章中,我们将进一步深入了解 fire,介绍其链式函数调用、自定义序列化、参数解析、fire 选项等更加高阶的功能。
『讲解开源项目系列』——让对开源项目感兴趣的人不再畏惧、让开源项目的发起者不再孤单。跟着我们的文章,你会发现编程的乐趣、使用和发现参与开源项目如此简单。欢迎留言联系我们、加入我们,让更多人爱上开源、贡献开源~
Google 开源的 Python 命令行库:深入 fire(一)的更多相关文章
- Google 开源的 Python 命令行库:fire 实现 git 命令
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- Google 开源的 Python 命令行库:初探 fire
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- Google 开源的 Python 命令行库:深入 fire(二)
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- 大家都说好用的 Python 命令行库:click
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- Python进阶:都说好用的 Python 命令行库click
click 是一个以尽可能少的代码.以组合的方式创建优美的命令行程序的 Python 包.它有很高的可配置性,同时也能开箱即用. 它旨在让编写命令行工具的过程既快速又有趣,还能防止由于无法实现预期的 ...
- 用什么库写 Python 命令行程序?看这一篇就够了
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- 让你如绅士般基于描述编写 Python 命令行工具的开源项目:docopt
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- Python 命令行之旅 —— 初探 argparse
『讲解开源项目系列』启动--让对开源项目感兴趣的人不再畏惧.让开源项目的发起者不再孤单.跟着我们的文章,你会发现编程的乐趣.使用和发现参与开源项目如此简单.欢迎联系我们给我们投稿,让更多人爱上开源.贡 ...
- Python 命令行之旅:使用 docopt 实现 git 命令
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
随机推荐
- php配置文件php.ini中文详解
转自:http://www.cnblogs.com/hbl/archive/2008/02/15/1069367.html [PHP] ; PHP还是一个不断发展的工具,其功能还在不断地删减 ; 而p ...
- DOTA轮播
原文:DOTA轮播 本人录制技术视频地址:https://edu.csdn.net/lecturer/1899 欢迎观看. 这一节介绍一下Dota轮播,先看看最终效果图. 一.HTML代码分析: &l ...
- 如何用Chrome浏览器下载网页音乐视频
打开网页,先让要下载的视频播放,右键单击选择审查元素(F12),选择上方的Network选项,按F5刷新,这个时候我们可以看到框架中Size下的不少文件数据数字正在变大,按size降序排列.点击表格的 ...
- Java发送邮件的工具类
package com.csice.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNot ...
- laravel 5.6 请教邮件中的cc,bcc是什么意思,有什么用?
cc指抄送 bcc指暗送. cc:carbon copy bcc:blind carbon copy
- win10访问Microsoft数据库问题总结
今天突然接到任务 把15年的一个wpf项目倒腾出来,根据客户要求微调界面效果 翻扯项目历史记录,找到最后一版的项目,不过历经三载,开发时的环境和现在的环境略有差距 原来:win7 64位 vs20 ...
- h5的canvas绘制方格(边框随即色)
文章地址 https://www.cnblogs.com/sandraryan/ 两个循环绘制 <body> <canvas id="cv" width=&quo ...
- jieba分词工具的使用方法
作为我这样的萌新,python代码的第一步是:#coding=utf-8 环境:python3.5+jieba0.39 一.jieba包安装方法: 方法1:使用conda安装 conda instal ...
- Wunder Fund Round 2016 (Div. 1 + Div. 2 combined)
现在水平真的不够.只能够做做水题 A. Slime Combining 题意:就是给n个1给你.两个相同的数可以合并成一个数,比如说有两个相同的v,合并后的值就是v+1 思路:直接模拟栈 #inclu ...
- H3C 基于ACL的包过滤技术