开云-Google 开源的 Python 命令行库:深入 fire(二)

Google 开源的 Python 号令行库:深切 fire(二) 时候:2024-12-13 21:19:13 手机看文章

扫描二维码随时随地手机看文章

1、媒介

在上一篇文章中我们介绍了 fire的子号令、嵌套号令和属性拜候等内容,今天我们将继续深切领会 fire的其他功能。

本系列文章默许利用 Python 3 作为注释器进行讲授。若你仍在利用 Python 2,请留意二者之间语法和库的利用差别哦~
2、功能 2.1 最简号令实现

在上一节中,我们介绍了只要界说一个函数便可以实现号令行法式。好比:

import fire def english(): return 'Hello, fire!' def chinese(): return '你好,fire!' if __name__ == '__main__': fire.Fire()

但这还不是最简单的实现体例,fire乃至答应你经由过程界说变量的体例来实现号令行!上面的例子可以写成下面这类情势:

import fireenglish = 'Hello, fire!' chinese = '你好,fire!' if __name__ == '__main__': fire.Fire()
2.2 链式挪用

在 Fire CLI中,你可以经由过程链式挪用不竭地对上一个成果进行处置。

想做到这一点也很简单,就是在实例方式中返回 self便可。

鄙人面的示例中,我们实现了一个简单的四则运算号令,可链式挪用 add、sub、mul和 div。

import fire class Calculator: def __init__(self): self.result = 0 self.express = '0' def __str__(self): return f'{self.express} = {self.result}' def add(self, x): self.result += x self.express = f'{self.express}+{x}' return self def sub(self, x): self.result -= x self.express = f'{self.express}-{x}' return self def mul(self, x): self.result *= x self.express = f'({self.express})*{x}' return self def div(self, x): self.result /= x self.express = f'({self.express})/{x}' return self if __name__ == '__main__': fire.Fire(Calculator)

上述代码中的 add、sub、mul、div别离对应加、减、乘、除的逻辑,每一个方式都接管 x参数作为介入运算的数字,返回值均为 self,如许便可以无穷次地链式挪用。在号令行中链式挪用竣事后,会终究挪用到 __str__方式将成果打印出来。

此中,__str__在 fire顶用来完成自界说序列化。假如不供给这个方式,在链式挪用完成后将会打印帮忙内容。

好比,我们可以这么挪用:

美金 python calculator.py add 1 sub 2 mul 3 div 4((+1-2)*3)/4 = -0.75美金 python calculator.py add 1 sub 2 mul 3 div 4 add 4 sub 3 mul 2 div 1((((0+1-2)*3)/4+4-3)*2)/1 = 0.5
2.3 位置参数和选项参数

经由过程前面的介绍我们也都清晰了在 fire中没必要显式的界说位置参数或选项参数。

经由过程下面的例子,我们将细化两类参数的利用:

import fire class Building(object): def __init__(self, name, stories=1): self.name = name self.stories = stories def __str__(self): return f'name: {self.name}, stories: {self.stories}' def climb_stairs(self, stairs_per_story=10): yield self.name for story in range(self.stories): for stair in range(1, stairs_per_story): yield stair yield 'Phew!' yield 'Done!' if __name__ == '__main__': fire.Fire(Building)
组织函数中界说的参数(如 name和 stories)在号令行中仅为选项参数(如 --name和 --stories)。我们可以这么挪用:
美金 python example.py --name="Sherrerd Hall" --stories=3
组织函数中界说的参数可在号令中放在肆意位置。好比下面两个挪用都是可以的:
美金 python example.py --name="Sherrerd Hall" climb-stairs --stairs-per-story 10美金 python example.py climb-stairs --stairs-per-story 10 --name="Sherrerd Hall" 
组织函数和通俗方式中界说的默许参数(如 stories),在号令行中是可选的。我们可以这么挪用:
美金 python example.py --name="Sherrerd Hall" 
通俗方式中界说的参数(如 stairs_per_story)在号令行中便可所以位置参数,也能够是选项参数。我们可以这么挪用:
# 作为位置参数 美金 python example.py --name="Sherrerd Hall" climb_stairs 10 # 作为选项参数 美金 python example.py --name="Sherrerd Hall" climb_stairs --stairs_per_story=10
选项参数中的横杠(-)和下划线(_)是等价的。是以也能够这么挪用:
# 作为选项参数 美金 python example.py --name="Sherrerd Hall" climb_stairs --stairs-per-story=10

另外,fire还撑持在函数中界说 *args和 **kwargs。

import fire def fargs(*args): return str(args) def fkwargs(**kwargs): return str(kwargs) if __name__ == '__main__': fire.Fire()
函数中的 *args在号令行中为位置参数。我们可以这么挪用:
美金 python example.py fargs a b c
函数中的 **kwargs在号令行中为选项参数。我们可以这么挪用:
美金 python example.py fargs --a a1 --b b1 --c c1
经由过程分隔符 -可显式奉告分隔符后的为子号令,而横死令的参数。且看下面的示例:
# 没有利用分隔符,upper 被作为位置参数 美金 python example.py fargs a b c upper('a', 'b', 'c', 'upper') # 利用了分隔符,upper 被作为子号令 美金 python example.py fargs a b c - upper('A', 'B', 'C')
经由过程 fire内置的 --separator可以自界说分隔符,此选项参数需要跟在零丁的 --后面:
美金 python example.py a b c X upper -- --separator=X('A', 'B', 'C')
2.4 参数类型

在 fire中,参数的类型由其值决议,经由过程下面的简单代码,我们可以看到给分歧的值时,fire会解析为何类型:

import firefire.Fire(lambda obj: type(obj).__name__)
美金 python example.py 10int美金 python example.py 10.0 float 美金 python example.py hellostr美金 python example.py '(1,2)' tuple美金 python example.py [1,2]list美金 python example.py Truebool美金 python example.py {name: David}dict

假如想传递字符串情势的数字,那就需要谨慎引号了,要末把引号引发来,要末转义引号:

# 数字 10 美金 python example.py 10int # 没有对引号处置,依然是数字10 美金 python example.py "10" int # 把引号引发来,所所以字符串“10” 美金 python example.py '"10"' str # 另外一种把引号引发来的情势 美金 python example.py "'10'" str # 转义引号 美金 python example.py \"10\"str

斟酌下更复杂的场景,假如传递的是字典,在字典中有字符串,那末也是要谨慎引号的:

# 保举做法 美金 python example.py '{"name": "David Bieber"}' dict # 也是可以的 美金 python example.py {"name":'"David Bieber"'}dict # 毛病,会被解析为字符串 美金 python example.py {"name":"David Bieber"}str # 毛病,不会作为单个参数(由于中心有空格),报错 美金 python example.py {"name": "David Bieber"}

假如值为 True或 False将为视为布尔值,fire还撑持经由过程 --name将 name设为 True,或经由过程 --noname将 name设为 False:

美金 python example.py --obj=Truebool美金 python example.py --obj=Falsebool美金 python example.py --objbool美金 python example.py --noobjbool
2.5 Fire 内置选项参数

Fire 内置了一些选项参数,以帮忙我们更轻易地利用号令行法式。若想利用内置的选项功能,需要将选项参数跟在 --后,在上文中,我们介绍了 --separator参数,除它,fire还撑持以下选项参数:

command -- --help列出具体的帮忙信息 command -- --interactive进入交互式模式 command -- --completion [shell]生成 CLI 法式的主动补全剧本,以撑持主动补全 command -- --trace获得号令的 Fire 追踪以领会挪用 Fire 后事实产生了甚么 command -- --verbose获得包括私有成员在内的详情 3、小结

fire让号令行法式的实现变得特殊简单,本文侧重介绍了它的链式挪用、选项参数、位置参数、参数类型和内置选项参数。fire的概念其实不多,真正践行了“把简单留给他人,把复杂留给本身”的理念。

欲知详情,请下载word文档 下载文档

上一篇:开云-FPGA实现串口升级及MultiBoot(四)MultiBoot简介 下一篇:开云-通过 Django Pagination 实现简单分页