函数式编程
高阶函数
变量可以指向函数
print(abs(-10)) # 10 abs_func=abs
print(abs_func(-10)) # 10函数名也是变量
例如abs
就是一个指向获取绝对值的函数,我们可以试着将abs
指向其它对象,这时abs
也就无法完成获取绝对值传入参数
函数可以接收另外一个函数作为参数def my_funcparam_func(x, y, f): return f(x)+f(y)
print(my_funcparam_func(10,-10,abs)) #20
map/reduce
map用法
map将传入的参数依次作用域每个元素,将结果作为Iterator
返回r1=map(my_func_xx,[1,2,3,4,5]) list1=list(r1) #因为返回的时Iterator惰性序列,使用list将整个序列计算返回list
print(list1) # [1, 4, 9, 16, 25]reduce用法
reduce
把一个函数作用在一个序列上,这个函数接收两个参数,将结果继续和下一个元素做累计运算from functools import reduce def my_func_add(x, y):
return x+y
list2=reduce(my_func_add,[1,2,3,4])
print(list2) #10filter
filter
将传入函数依次作用于每个元素,然后根据返回值为True
或者False
,决定保留或者丢弃该元素
def my_is_odd(x):
return x%2==0
#返回的还是Iterator的惰性序列
list3=list(filter(my_is_odd, [1,2,4,5,6]))
print(list3) #[2, 4, 6]
排序
sorted
函数
list4=[1, 2,-4,0,-3]
#直接用sorted函数排序
sorted(list4) # [-4, -3, 0, 1, 2]
sorted(['bob', 'about', 'Zoo', 'Credit']) #['Credit', 'Zoo', 'about', 'bob']
#用关键字排序
sorted(list4, key=abs) #[0, 1, 2, -3, -4]
#反向排序
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
默认对字符串的排序,按照ASCII码大小比较,
key
指定的函数作用域list的每个元素.并根据返回结果进行排序
返回函数
函数作为结果值进行返回
def my_lazy_sum(*args):
def my_sum():
sum=0
for x in args:
sum+=x
return sum
return my_sum
my_f=my_lazy_sum(1,2,3,4)
my_f() #10
在函数内部又定义了函数,内部函数可以引用外部函数的参数和局部变量,当外部函数返回内部函数时,参数和变量都保存在返回的函数中,这就是闭包
闭包
注意:返回的函数并不会立即执行,而是直到调用才执行,因此函数内用到的变量是执行时的变量值,为了避免:返回函数时,不要饮用任何循环变量或后续会变化的变量
匿名函数
lambda
关键字表示匿名函数,冒号前为函数参数
匿名函数也可以作为返回值
my_f2=lambda x: x*x
print(my_f2(2)) #4
装饰器
函数有__name__
属性,可以拿到函数的名字
def my_func_now(x):
return x*3
name=my_func_now.__name__
print(name) #my_func_now
定义一个装饰器decorator
def my_custom_decorator(func):
def my_wrapper(*args, **kw):
print("call %s()"%func.__name__)
return func(*args, **kw)
return my_wrapper
用装饰器装饰一个函数
@my_custom_decorator #相当于执行了my_log=my_custom_decorator(my_log)
def my_log():
print("my_log_func")
my_log()
#call my_log()
# my_log_func
在执行my_log
函数不仅会执行函数本身,还会运行装饰器的my_wrapper
函数
decorator
还可以传入参数,就需要更复杂的3层嵌套
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
@log('execute') #3层嵌套相当于: now = log('execute')(now)
def now():
print('2015-3-25')
#execute now():
#2015-3-25
当需要在装饰器中获取到真正执行的函数名称时,我们可以使用
Python
内置的functools.wraps
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__) #此时获取到的name为装饰的函数名称,而不是wrapper
return func(*args, **kw)
return wrapper
偏函数
使用functools.partial
将函数的某些参数固定住(设置默认值),返回一个新的函数
import functools
int2=functools.partial(int, base=2)
print(int2("100")) #4
实际functools.partial
接受三个参数:函数对象、*args
、**kw
,会将*args
参数部分自动加到函数对象的左边,而将**kw
一部分自动加到右边