## Hello World

``````# calc.py
import fire

class Calculator(object):
"""A simple calculator class."""

def double(self, number):
return 2 * number

if __name__ == '__main__':
fire.Fire(Calculator)

``````> python calc.py double 10
20
> python calc.py double --number=16
32

## 实战

``````import math
import fire

class Math(object):

def pi(self, n):
s = 0.0
for i in range(n):
s += 1.0/(i+1)/(i+1)
return math.sqrt(6*s)

def fact(self, n):
s = 1
for i in range(n):
s *= (i+1)
return s

if __name__ == '__main__':
fire.Fire(Math)

``````>  python maths.py pi 10000
3.14149716395
>  python maths.py pi 100000
3.14158310433
>  python maths.py pi 1000000
3.14159169866
>  python maths.py fact 10
3628800
>  python maths.py fact 15
1307674368000
>  python maths.py fact 20
2432902008176640000

Cool，真的非常方便！fire对当前对象结构进行了暴露，将结构信息映射到shell命令行参数上。fire其实有多种暴露模式，接下来我们逐个来看fire都有哪些暴露模式。

## 暴露模块

fire如果不传递任何参数就可以直接暴露当前模块结构，我们对上面的例子做一下改造，去掉类信息

``````import math
import fire

def pi(n):
s = 0.0
for i in range(n):
s += 1.0/(i+1)/(i+1)
return math.sqrt(6*s)

def fact(n):
s = 1
for i in range(n):
s *= (i+1)
return s

if __name__ == '__main__':
fire.Fire()

``````>  python maths.py fact 20
2432902008176640000
>  python maths.py pi 1000000
3.14159169866

## 暴露函数

fire还可以传递一个函数对象来暴露单个函数，可以让我们在命令行参数上省掉函数名称

``````import math
import fire

def pi(n):
s = 0.0
for i in range(n):
s += 1.0/(i+1)/(i+1)
return math.sqrt(6*s)

if __name__ == '__main__':
fire.Fire(pi)

``````>  python maths.py 1000
3.14063805621

## 暴露字典

fire可以直接暴露一个模块，将当前模块的所有函数全部暴露，函数名和第一个参数名一致。我们也可以不用暴露整个模块的所有函数，使用字典暴露法就可以选择性地对模块的某些函数进行暴露，顺便还可以替换暴露出来的函数名称。

``````import math
import fire

def pi(n):
s = 0.0
for i in range(n):
s += 1.0/(i+1)/(i+1)
return math.sqrt(6*s)

def fact(n):
s = 1
for i in range(n):
s *= (i+1)
return s

if __name__ == '__main__':
fire.Fire({
"pi[n]": pi
})

``````>  python maths.py pi[n] 1000
3.14063805621

``````>  python maths.py pi 1000
Fire trace:
1. Initial component
2. ('Cannot find target in dict:', 'pi', {'pi[n]': <function pi at 0x10a062c08>})

Type:        dict
String form: {'pi[n]': <function pi at 0x10a062c08>}
Length:      1

Usage:       maths.py
maths.py pi[n]

## 暴露对象

``````import math
import fire

class Maths(object):

def pi(self, n):
s = 0.0
for i in range(n):
s += 1.0/(i+1)/(i+1)
return math.sqrt(6*s)

def fact(self, n):
s = 1
for i in range(n):
s *= (i+1)
return s

if __name__ == '__main__':
fire.Fire(Maths())

``````>  python maths.py pi 1000
3.14063805621
>  python maths.py fact 20
2432902008176640000

## 类 vs 对象

``````import math
import fire

class Maths(object):

def __init__(self, coeff):
self.coeff = coeff

def pi(self, n):
s = 0.0
for i in range(n):
s += 1.0/(i+1)/(i+1)
return self.coeff * math.sqrt(6*s)

def fact(self, n):
s = 1
for i in range(n):
s *= (i+1)
return self.coeff * s

if __name__ == '__main__':
fire.Fire(Maths)

``````> python maths.py pi 1000 --coeff=2
6.28127611241

``````> python maths.py pi 1000
Fire trace:
1. Initial component
2. ('The function received no value for the required argument:', 'coeff')

Type:        type
String form: <class '__main__.Maths'>
Line:        5

Usage:       maths.py COEFF
maths.py --coeff COEFF

## 暴露属性

``````> python maths.py coeff --coeff=2
2
> python maths.py coeff --coeff=3
3

``````# example.py
import fire
english = 'Hello World'
spanish = 'Hola Mundo'
fire.Fire()

``````\$ python example.py english
Hello World
\$ python example.py spanish
Hola Mundo

## 链式暴露

``````import fire

class Chain(object):

def __init__(self):
self.value = 1

def incr(self):
print "incr", self.value
self.value += 1
return self

def decr(self):
print "decr", self.value
self.value -= 1
return self

def get(self):
return self.value

if __name__ == '__main__':
fire.Fire(Chain)

``````> python chains.py incr incr incr decr decr get
incr 1
incr 2
incr 3
decr 4
decr 3
2

Cool! 我们通过在每个方法里面方法self对象自身来实现了漂亮的链式调用效果。

``````# xyz.py
import fire

value = "hello"

if __name__ == '__main__':
fire.Fire()

``````> python xyz.py value
hello
> python xyz.py value upper
HELLO
> python xyz.py value upper lower
Traceback (most recent call last):
File "xyz.py", line 7, in <module>
fire.Fire()
File "/Users/pyloque/source/pys/.py/lib/python2.7/site-packages/fire/core.py", line 127, in Fire
component_trace = _Fire(component, args, context, name)
File "/Users/pyloque/source/pys/.py/lib/python2.7/site-packages/fire/core.py", line 366, in _Fire
component, remaining_args)
File "/Users/pyloque/source/pys/.py/lib/python2.7/site-packages/fire/core.py", line 542, in _CallCallable
result = fn(*varargs, **kwargs)
TypeError: upper() takes no arguments (1 given)

``````> python xyz.py value upper - lower
hello
> python xyz.py value upper - lower - upper
HELLO
> python xyz.py value upper - lower - upper - lower
hello

## 让redis-py秒变命令行

``````import fire
import redis

if __name__ == '__main__':
fire.Fire(redis.StrictRedis)

``````>  python client.py flushdb
True
>  python client.py set codehole superhero
True
>  python client.py get codehole
superhero
>  python client.py exists codehole
True
>  python client.py keys "*"
codehole
>  python client.py delete codehole
1
# 指定地址
> python client.py set codehole superhero --host=127.0.0.1 --port=6379
True