介绍 python advanced skill。
Advanced Features
Let’s move on to advanced features.
Lambda functions
A Lambda Function is a small, anonymous function — anonymous in the sense that it doesn’t actually have a name. A lambda function can take any number of arguments, but must always have only one expression:
lambda 函数是一种 内联函数 inline function,调用成本小,时空开销很小。
1
2
3
4
|
x = lambda a, b : a * b
print(x(5, 6)) # prints '30' # 匿名函数也是函数,调用的时候使用这样的方式
x = lambda a : a*3 + 3
print(x(3)) # prints '12'
|
lambda表达式的基本语法如下:
lambda arg1,arg2,arg3… :<表达式>
arg1/arg2/arg3为函数的参数(函数输入),表达式相当于函数体,运算结果是表达式的运算结果。
Python 中定义函数有两种方法,一种是用常规方式 def 定义,函数要指定名字,第二种是用 lambda 定义,不需要指定名字,称为 Lambda 函数。lambda 函数的使用场景:当逻辑比较简单的时候,没有必要起个名字或者说取一个优雅的名字是很费劲的事情。 下面两种定义是等价的。
1
2
3
4
5
6
7
|
def add1(x, y):
return x+y
print(add1(1, 2))
add2 = lambda x, y: x+y
print(add2(1,2))
|
如果是使用 匿名函数(lambda 表达式),还有有一个名字(如上所示),有点画蛇添足。通常是直接使用 lambda 表达式的。
map
map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。
1
2
3
|
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(r)
|
reduce
(找找这种 reduce的感觉)
reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
1
|
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
|
如果要把序列[1, 3, 5, 7, 9]变换成整数13579,reduce就可以派上用场:
1
2
3
|
def fn(x, y): return x*10 +y
reduce(fn, [1, 3, 5, 7, 9]) # 输出是 13579
|
filter
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
1
2
3
4
|
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]
|
Maps
Map() is a built-in Python function used to apply a function to a sequence of elements like a list or dictionary. It’s a very clean and most importantly readable way to perform such an operation.
相对于 lambda, map 使用的频率更少了。 最后返回的是一个list。
这个函数的强大之处在于,对于每一个变量都是应用这个function的, 属于element-wise 的操作。
1
2
3
4
5
6
7
8
9
10
11
|
def square_it_func(a):
return a * a
x = map(square_it_func, [1, 4, 7])
print(x) # prints '[1, 16, 49]'
def multiplier_func(a, b):
return a * b
x = map(multiplier_func, [1, 4, 7], [2, 5, 8])
print(x) # prints '[2, 20, 56]'
|
Filtering
The Filter built-in function is quite similar to the Map function in that it applies a function to a sequence (list, tuple, dictionary). The key difference is that filter() will only return the elements which the applied function returned as True.
只是返回符合某种条件的element
1
2
3
4
5
6
7
8
9
10
11
|
# Our numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
# Function that filters out all numbers which are odd
def filter_odd_numbers(num):
if num % 2 == 0:
return True
else:
return False
filtered_numbers = filter(filter_odd_numbers, numbers)
print(filtered_numbers)
# filtered_numbers = [2, 4, 6, 8, 10, 12, 14]
|
1
2
3
4
5
6
|
from itertools import *
def check_for_drop(x):
print ('Checking: ', x)
return (x > 5)
for i in dropwhile(check_for_drop, [2, 4, 6, 8, 10, 12]):
print ('Result: ', i)
|
List Comprehension
常见的几种形式:
(An iterable is something you can loop over)
list comprehensions vs loops:
- list comprehensions are more efficient both computationally and coding space
- Every list comprehension can be rewritten as a for loop, but not every for loop can be rewritten as a list comprehension.
从优化的角度 list comprehensions是优于 for loop 中的if else 操作的。因为前者是 predicatable pattern 是可以预测的。
However, keep in mind that list comprehensions are faster because they are optimized for the Python interpreter to spot a predictable pattern during looping.
a small code demo:在于使用功能 timeit libary 进行函数的计时比较。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import timeit
def squares(size):
result = []
for number in range(size):
result.append(number * number)
return result
def squares_comprehension(size):
return [number * number for number in range(size)]
print(timeit.timeit("squares(50)", "from __main__ import squares", number=1_000_000))
print(timeit.timeit("squares_comprehension(50)", "from __main__ import squares_comprehension", number=1_000_000))
|
more complex list comprehensions:
这种if 的写法 是两个进行并列的。其实可以写成
1
2
3
4
5
6
|
numbers = [1, 2, 3, 4, 5, 6, 18, 20]
squares = [number for number in numbers if number % 2 == 0 if number % 3 == 0]
# or
squares = [number for number in numbers if number % 2 == 0 and number % 3 == 0]
print(squares)
# output: [6, 18]
|
在 output expression 中,也是可以使用 if else 进行进一步输出筛选。
1
2
3
4
5
|
numbers = [1, 2, 3, 4, 5, 6, 18, 20]
squares = ["small" if number < 10 else "big" for number in numbers if number % 2 == 0 if number % 3 == 0]
print(squares)
ouput: ['small', 'big']
|
converting nested loops into list comprehension
代码功能: 都是把二维的 matrix 转成了一个 list (flattened)
1
2
3
4
5
6
|
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = []
for row in matrix:
for item in row:
flattened.append(item)
print(flattened)
|
注意这个顺序,先是row in matrix 然后是 item in row.(对于这个顺序的理解,其实是可以看成二重循环的)
1
2
3
|
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [item for row in matrix for item in row]
print(flattened)
|
ouput matric from nested list comprehensions:
1
2
|
matrix = [[item for item in range(5)] for row in range(3)]
print(matrix)
|
对于 dictionary 的支持: 主要是 dict1.items() 和 key, value 的使用。还有一种实现方式 zip(list1, list2)
1
2
3
|
prices = {"beer": 2, "fish": 5, "apple": 1}
float_prices = {key:float(value) for key, value in prices.items()}
print(float_prices)
|
从代码的角度,可以看出,操作和最后的返回的形式是没有很大的关系,上面是 [], 这个是 {}, 分别对应的是 list 和 set 两种不同的格式。
1
2
3
|
numbers = [10, 10, 20, 30, 12, -20, 0, 1]
unique_squares = {number**2 for number in numbers}
print(unique_squares)
|
Containers
Python includes several built-in container types: lists, dictionaries, sets, and tuples.
- lists
A list is the Python equivalent of an array, but is resizeable and can contain elements of different types:
1
2
|
x = xs.pop() # Remove and return the last element of the list
print x, xs
|
In addition to accessing list elements one at a time, Python provides concise syntax to access sublists; this is known as slicing:
1
2
3
4
5
6
7
8
9
|
nums = range(5) # range is a built-in function that creates a list of integers
print nums # Prints "[0, 1, 2, 3, 4]"
print nums[2:4] # Get a slice from index 2 to 4 (exclusive); prints "[2, 3]"
print nums[2:] # Get a slice from index 2 to the end; prints "[2, 3, 4]"
print nums[:2] # Get a slice from the start to index 2 (exclusive); prints "[0, 1]"
print nums[:] # Get a slice of the whole list; prints ["0, 1, 2, 3, 4]"
print nums[:-1] # Slice indices can be negative; prints ["0, 1, 2, 3]"
nums[2:4] = [8, 9] # Assign a new sublist to a slice
print nums # Prints "[0, 1, 8, 9, 4]"
|
- dictionary
A dictionary stores (key, value) pairs, similar to a Map in Java or an object in Javascript. You can use it like this:
1
2
3
4
|
d = {'cat': 'cute', 'dog': 'furry'} # Create a new dictionary with some data
print d.get('monkey', 'N/A') # Get an element with a default; prints "N/A"
print d.get('fish', 'N/A') # Get an element with a default; prints "wet"
|
- sets
A set is an unordered collection of distinct elements. As a simple example, consider the following:
1
2
3
4
5
6
7
8
9
10
11
12
|
animals = {'cat', 'dog'}
animals.add('fish') # Add an element to a set
print len(animals) # Number of elements in a set;
animals.remove('cat') # Remove an element from a set
print len(animals)
animals = {'cat', 'dog', 'fish'}
for idx, animal in enumerate(animals):
print '#%d: %s' % (idx + 1, animal)
# Prints "#1: fish", "#2: dog", "#3: cat"
|
- tuples
A tuple is an (immutable) ordered list of values. A tuple is in many ways similar to a list; one of the most important differences is that tuples can be used as keys in dictionaries and as elements of sets, while lists cannot. Here is a trivial example:
1
2
3
4
5
|
d = {(x, x + 1): x for x in range(10)} # Create a dictionary with tuple keys
t = (5, 6) # Create a tuple
print type(t)
print d[t]
print d[(1, 2)]
|
元组类似于列表,是一个基于位置的有序对象集合,但是元组一旦创建之后就不能更改,因此列表中修改元素的操作对于元组都不适用。
元组和其他不可变量类似于其他语言中“常量”的声明,它的不可变性提供了某种一致性,这样可以确保元组在程序中不会被另一个引用修改。
Mark Lutz——《Learning Python》中文版
注意,dict内部存放的顺序和key放入的顺序是没有关系的。
和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key的增加而增加;
- 需要占用大量的内存,内存浪费多。
而list相反:
- 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。
dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key。
使用zip函数, 把key和value的list组合在一起, 再转成字典(dict).
1
2
3
4
|
keys = ['a', 'b', 'c']
values = [1, 2, 3]
dictionary = dict(zip(keys, values))
print dictionary
|
创建同样大小的list和tuple,可以看到list的时间开销几乎是tuple的10倍。对两个大表进行遍历,tuple与list速度相似。储存同样元素的list和tuple, list有更多空间开销。tuple是 immutable, 所以它是可哈希的(hashable)的。这使得tuple可以作为dict的key,或者扔进set里,list则不行。
在Python中:
list、set和dictionary 都是可改变的,比如可以通过list.append(),set.remove(),dict[‘key’] = value对其进行修改,所以它们都是不可哈希的;而tuple和string是不可变的,只可以做复制或者切片等操作,所以它们就是可哈希的。
因为list 中没有 __hash__
这个函数,所以不是hashable的,但是为什么呢?这个解释可能更加本质深入一些:Python 为什么list不能作为字典的key?
- namedtuple
tuple是不可变序列,当你不希望外界可以随意的改变你的函数返回值的时候,不妨将你的返回值以tuple的形式返回,tuple还可以做为字典的key,这些都是tuple的独到之处,此外,由于存储的方式不同,相同元素的tuple 要比list更快,使用的内存更少。tuple虽然有这么多优点,但是呢,在使用的时候,你不得不用下角标来访问它的元素,这样对于代码的可读性来说是一种折损。namedtuple弥补了tuple的这一缺陷,使得你可以像使用对象属性那样去访问数据.
namedtuple能够用来创建类似于元祖的数据类型,除了能够用索引来访问数据,能够迭代,更能够方便的通过属性名来访问数据。这个相当于是 tuple 和dictionary 的综合体。主要这个值是只读的,不能修改。
1
2
3
4
5
|
from collections import namedtuple
Animals =nametuple('Animal', 'name age type')
big_yellow =Animals(name ='big_yellow', age=3, type=‘dog’)
// 访问的话使用
big_yellow.name
|
numpy
Arrays
A numpy array is a grid of values, all of the same type, and is indexed by a tuple of nonnegative integers.
1
2
3
4
|
a = np.array([1, 2, 3]) # Create a rank 1 array
print type(a), a.shape, a[0], a[1], a[2]
a[0] = 5 # Change an element of the array
print a
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
a = np.zeros((2,2)) # Create an array of all zeros
print a
b = np.ones((1,2)) # Create an array of all ones
print b
c = np.full((2,2), 7) # Create a constant array
print c
d = np.eye(2) # Create a 2x2 identity matrix
print d
e = np.random.random((2,2)) # Create an array filled with random values
print e
|
Boolean array indexing: Boolean array indexing lets you pick out arbitrary elements of an array. Frequently this type of indexing is used to select the elements of an array that satisfy some condition. Here is an example:
1
2
3
4
5
6
7
8
9
10
|
import numpy as np
a = np.array([[1,2], [3, 4], [5, 6]])
bool_idx = (a > 2) # Find the elements of a that are bigger than 2;
# this returns a numpy array of Booleans of the same
# shape as a, where each slot of bool_idx tells
# whether that element of a is > 2.
print bool_idx
|
Array math
Basic mathematical functions operate elementwise on arrays, and are available both as operator overloads and as functions in the numpy module:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)
# Elementwise sum; both produce the array
print x + y
print np.add(x, y)
# Elementwise difference; both produce the array
print x - y
print np.subtract(x, y)
# Elementwise product; both produce the array
print x * y
print np.multiply(x, y)
# Elementwise division; both produce the array
# [[ 0.2 0.33333333]
# [ 0.42857143 0.5 ]]
print x / y
print np.divide(x, y)
# Elementwise square root; produces the array
# [[ 1. 1.41421356]
# [ 1.73205081 2. ]]
print np.sqrt(x)
|
Note that unlike MATLAB, *
is elementwise multiplication, not matrix multiplication. We instead use the dot function to compute inner products of vectors, to multiply a vector by a matrix, and to multiply matrices. dot is available both as a function in the numpy module and as an instance method of array objects:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
x = np.array([[1,2],[3,4]])
y = np.array([[5,6],[7,8]])
v = np.array([9,10])
w = np.array([11, 12])
# Inner product of vectors; both produce 219
print v.dot(w)
print np.dot(v, w)
x = np.array([[1,2],[3,4]])
print np.sum(x) # Compute sum of all elements; prints "10"
print np.sum(x, axis=0) # Compute sum of each column; prints "[4 6]"
print np.sum(x, axis=1) # Compute sum of each row; prints "[3 7]"
print x
print x.T
|
Broadcasting
Broadcasting is a powerful mechanism that allows numpy to work with arrays of different shapes when performing arithmetic operations. Frequently we have a smaller array and a larger array, and we want to use the smaller array multiple times to perform some operation on the larger array.
For example, suppose that we want to add a constant vector to each row of a matrix. We could do it like this:
1
2
3
4
5
6
7
8
|
import numpy as np
# We will add the vector v to each row of the matrix x,
# storing the result in the matrix y
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y = x + v # Add v to each row of x using broadcasting
print y
|
1
2
3
4
5
6
7
8
|
# Compute outer product of vectors
v = np.array([1,2,3]) # v has shape (3,)
w = np.array([4,5]) # w has shape (2,)
# To compute an outer product, we first reshape v to be a column
# vector of shape (3, 1); we can then broadcast it against w to yield
# an output of shape (3, 2), which is the outer product of v and w:
print np.reshape(v, (3, 1)) * w
|
(对于第 4 点还是挺有趣的, 多看看,其实不是很懂)
Broadcasting two arrays together follows these rules:
- If the arrays do not have the same rank, prepend the shape of the lower rank array with 1s until both shapes have the same length.
- The two arrays are said to be compatible in a dimension if they have the same size in the dimension, or if one of the arrays has size 1 in that dimension.
- The arrays can be broadcast together if they are compatible in all dimensions.
- After broadcasting, each array behaves as if it had shape equal to the elementwise maximum of shapes of the two input arrays.
- In any dimension where one array had size 1 and the other array had size greater than 1, the first array behaves as if it were copied along that dimension
好好理解这几个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
# Compute outer product of vectors
v = np.array([1,2,3]) # v has shape (3,)
w = np.array([4,5]) # w has shape (2,)
# To compute an outer product, we first reshape v to be a column
# vector of shape (3, 1); we can then broadcast it against w to yield
# an output of shape (3, 2), which is the outer product of v and w:
print np.reshape(v, (3, 1)) * w
# Add a vector to each row of a matrix
x = np.array([[1,2,3], [4,5,6]])
# x has shape (2, 3) and v has shape (3,) so they broadcast to (2, 3),
# giving the following matrix:
print x + v
# Add a vector to each column of a matrix
# x has shape (2, 3) and w has shape (2,).
# If we transpose x then it has shape (3, 2) and can be broadcast
# against w to yield a result of shape (3, 2); transposing this result
# yields the final result of shape (2, 3) which is the matrix x with
# the vector w added to each column. Gives the following matrix:
print (x.T + w).T
# Another solution is to reshape w to be a row vector of shape (2, 1);
# we can then broadcast it directly against x to produce the same
# output.
print x + np.reshape(w, (2, 1))
:
# Multiply a matrix by a constant:
# x has shape (2, 3). Numpy treats scalars as arrays of shape ();
# these can be broadcast together to shape (2, 3), producing the
# following array:
print x * 2
|
Matplotlib
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
import matplotlib.pyplot as plt
# Compute the x and y coordinates for points on a sine curve
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
# Plot the points using matplotlib
plt.plot(x, y)
# 有 x y 轴的
y_cos = np.cos(x)
# Plot the points using matplotlib
plt.plot(x, y_sin)
plt.plot(x, y_cos)
plt.xlabel('x axis label')
plt.ylabel('y axis label')
plt.title('Sine and Cosine')
plt.legend(['Sine', 'Cosine'])
# subplots 的图像
# Compute the x and y coordinates for points on sine and cosine curves
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# Set up a subplot grid that has height 2 and width 1,
# and set the first such subplot as active.
plt.subplot(2, 1, 1)
# Make the first plot
plt.plot(x, y_sin)
plt.title('Sine')
# Set the second subplot as active, and make the second plot.
plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title('Cosine')
# Show the figure.
plt.show()
|
python中的星号
在参数名之前使用一个星号,就是让函数接受任意多的位置参数。 (表示不定变量)
1
2
3
4
5
6
7
8
|
def multiply(*args):
res =1
for arg in args:
res *= arg
return res
print(multiply(2, 3))
print(multiply(2, 3, 4))
|
在参数名之前使用两个星号,来支持任意多的关键词参数
1
2
3
4
5
|
def accept(**kwargs):
for (key, val) in kwargs.items():
print("%s -> %s"%(key, val))
accept(foo ='bar', spam ='eggs')
|
在终端执行python
- 通过标准输入和管理
1
2
|
# 通过管道 传递内容给 python
echo "print('hi')" | python
|
下面的两种方式都是执行 spam.py 文件
1
2
3
4
|
# 重定向一个文件给 python
python < spam.py
# 正常执行
python spam.py
|
- 通过 -c 指定的字符串
当仅仅需要检查一行或者两行代码时候,可以参考这种方式。省去了进入交互解释器的麻烦。
1
2
|
# 使用 python 的 -c 参数
python -c "print('hi')"
|
- 对包使用 -m 参数
执行 Python 包的正确方法是使用 -m 并指定要运行的包名。
python中的逆序遍历
Reverse a List Using Slicing Operator
1
2
3
4
5
6
7
8
|
list1 =[1, 3, 5, 7]
# 这里的冒号其实是省略了两个参数
for item in list1[::-1]:
print(item)
# 其完整形式是
for item in list1[n-1::-1]:
print(item)
|
特别要注意第二个冒号前的那个缺省值,如果什么都不填,则一直遍历到列表的index=0的位置;如果填0,则默认一直遍历到列表的index =1的位置,如果填1,则默认一直遍历到列表的index =2的位置,依次往后。
而第一个冒号前的那个缺省值,默认是从index = n-1的位置(列表末位)开始数起,填几就从第几号索引开始。甚至可以填比n-1大的值,但是也还是从最后一位开始遍历。
Accessing Elements in Reversed Order
1
2
3
|
for item in reversed(list1):
print(item)
|
Reversing a list with list.reverse() method
1
2
|
list1 =[1, 2, 3, 4, 5]
reversed_list =list1.reverse()
|
reverse 是in-place 操作, reversed() 是返回一个list
python 中小的知识点
__init__
文件
1). 该文件的作用是将整个文件夹当做一个包了管理,每当外部有 import 的时候,就会自动执行里面的函数。(每当导入一个包后,就相当于导入了它的 init 文件)
2). 该文件里面可以什么都不写,只要求存在就行。
3). import 的两种格式
1
2
|
import spam.module
from spam import module
|
- pass 关键字
pass 关键字在于占坑。
- append 和extend 关键字
两者的差别:append 是一个list 和元素之间的操作;extend 是list 和list 之间的操作。
extend 举例说明
1
2
3
4
5
|
fruites = ['apple', 'banana', 'cherry']
cars =['Ford', 'BMW', 'Volvo']
fruites.extend(cars)
# ['apple', 'banana', 'cherry', 'Ford', 'BMW', 'Volvo']
# 不会改变list 的shape,增加的是其长度, 类似 += 的功能
|
1
2
3
4
5
6
|
if not os.path.exists(path):
os.makedirs(path)
# 可以简化为
os.makedirs(path, exist_ok =True)
|
vars()
vars() 函数返回对象 object 的属性和属性值的字典对象
语法
vars([object])
使用
1
2
3
4
5
6
7
|
class Runoob:
a =1
print(vars(Runoob))
# {'a': 1, '__module__': '__main__', '__doc__': None}
runoob = Runoob()
print(vars(runoob))
# {}
|
vars 一般用在解析命令行参数的时候,dictionary 貌似用在写函数上,不知道怎么回事。
总结常见的命令行工具
常见的包 python 内置的 args
, click
和 fire
fire是python中用于生成命令行界面(Command Line Interfaces, CLIs)的工具,不需要做任何额外的工作,只需要从主模块中调用fire.Fire(),它会自动将你的代码转化为CLI,Fire()的参数可以说任何的python对象
当不接参数时,执行python test_fire.py会显示帮助信息
单个函数:python 模块名 参数1 参数2
1
2
3
4
5
6
|
import fire
def add(a, b):
count = a + b
return count
if __name__ == '__main__':
fire.Fire(add)
|
多个函数:python 模块名 函数名 参数
1
2
3
4
5
6
7
8
9
|
import fire
def add(a, b):
count = a + b
return count
def sub(a, b):
result = a - b
return result
if __name__ == '__main__':
fire.Fire()
|
类(对象) 多个函数:python 模块名 函数名 参数
1
2
3
4
5
6
7
8
9
10
11
|
import fire
class Calculator(object):
def add(self, a, b):
count = a + b
return count
def sub(self, a, b):
result = a - b
return result
if __name__ == '__main__':
fire.Fire(Calculator) #注意这里使用的是类名 或者类的实例化对象
|
注意事项
- fire 默认使用 - 作为参数分隔符,所以如果你要在命令行传入类似 2017-04-22 的参数时,那么程序接收到的参数就肯定不是 2017-04-22 了,需要使用 –separator 来改变分隔符
- fire 会自动区分你在命令行传入的参数的类型,例如 20170422 会自动识别成 int,hello 会自动识别成 str,’(1,2)’ 会自动识别成 tuple,’{“name”: “Alan Lee”}’ 会自动识别成 dict。但是你如果想要传入一个字符串类型的 20170422 怎么办?那就需要这样写:’“20170422”’ 或者 “‘20170422’” 或者 “20170422”,总之呢,就是加一个转义,因为命令行默认会吃掉你的引号