【Python】自动生成命令行工具 - fire 简介

fire是python中用于生成命令行界面(Command Line Interfaces, CLIs)的工具,不需要做任何额外的工作,只需要从主模块中调用fire.Fire(),它会自动将你的代码转化为CLI,Fire()的参数可以说任何的python对象。

Python fire指南:

https://github.com/google/python-fire/blob/master/docs/guide.md 

 

用法
使用 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 来改变分隔符
fire 会自动区分你在命令行传入的参数的类型,例如 20170422 会自动识别成 int,hello 会自动识别成 str,'(1,2)' 会自动识别成 tuple,'{"name": "Alan Lee"}' 会自动识别成 dict。但是你如果想要传入一个字符串类型的 20170422 怎么办?那就需要这样写:'"20170422"' 或者 "'20170422'" 或者 \"20170422\",总之呢,就是加一个转义,因为命令行默认会吃掉你的引号。

参考 python fire 指南

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值