函数式
函数式:functional 一种编程范式
函数式编程是一种抽象计算的编程模式
特点:
把计算视为函数而非指令
纯函数式编程:不需要变量,没有副作用,测试简单
支持高阶函数,代码简洁
python
不是纯函数式编程:允许有变量
支持高阶函数:函数可以作为变量传入
支持闭包:有来闭包就能返回函数
有限的支持匿名函数
闭包(Closure)是词法闭包(Lexical Closure)的简称,
内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。它只不过是个“内层”的函数,由一个名字(变量)来指代,而这个名字(变量)对于“外层”包含它的函数而言,是本地变量。
返回函数不要引用任何循环变量,或者后续会发生变化的变量。
1. 希望一次返回3个函数,分别计算1x1,2x2,3x3:
def count():
fs = []
for i in range(1, 4):
def f(j):
def g():
return j*j
return g
r = f(i)
fs.append(r)
return fs
f1, f2, f3 = count()
print f1(), f2(), f3()
或者
def count():
fs = []
for i in range(1,4):
def f(j=i):
return j*j
fs.append(f)
return fs
f1,f2,f3 = count()
print f1(),f2(),f3()
作用:1.当闭包执行完后,仍然能够保持住当前的运行环境。
2.闭包可以根据外部作用域的局部变量来得到不同的结果,类似配置功能的作用,我们可以修改外部的变量,闭包根据这个变量展现出不同的功能。
高阶函数
变量可以指向函数
函数名其实就是窒息那该函数的变量
高阶函数:能接收函数作为参数
(Python为string对象提供了转换大小写的方法:upper() 和 lower().
还不止这些,Python还为我们提供了首字母大写,其余小写的capitalize()方法,
以及所有单词首字母大写,其余小写的title()方法.)
- map(f,list)
它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。(对元祖进行来“解包”操作) - reduce(f,list)
python3使用要导入functools
函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。
求和:
def f(x,y):
return x+y
reduce(f,[1,2,5,7,9])
3.filter(f,list)
收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
删除 None 或者空字符串:
def is_not_empty(s):
return s and len(s.strip()) > 0
filter(is_not_empty, ['test', None, '', 'str', ' ', 'END'])
#或匿名函数
print filter(lambda s: s and len(s.strip())>0, ['test', None, '', 'str', ' ', 'END'])
4.sorted(list,f)
传入两个待比较的元素 x, y,如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。
忽略大小写:
def cmp_ignore_case(s1, s2):
return cmp(s1.lower(), s2.lower())
print sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case)
匿名函数
不显示地定义函数,直接传入匿名函数更为方便
关键字lambda
匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果
装饰器 decorator
在函数运行时动态的增加功能,但不改动函数本身代码。可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能
通过高阶函数返回新函数
def f1(x):
return x*2
def new_fn(f): #装饰器
def fn(x):
print 'call' + f.__name__ + '()'
return f(x)
return fn
#调用装饰器
#1. 间接
# g1 = new_fn(f1)
# print g1(5)
#2. 彻底隐藏f1的原始定义函数
f1 = new_fn(f1)
print f1(f1)
python内置@语法简化装饰器调用
@new_fn
def f1(x):
return x*2
相当于
def f1(x):
return x*2
f1 = new_fn(f1)
简化代码,避免每个函数编写重复性代码
打印日志 @log
检测性能 @performance
数据库事物 @transaction
URL路由 @post(‘/register’)
*args 代表任意个普通参数,**kw代表任意个用=号指定默认值的参数
*args 是元组 、**kw是字典
无参数的 decorator
打印出函数调用的时间:
import time
def performance(f):
def fn(*args, **kw):
t1 = time.time()
r = f(*args, **kw)
t2 = time.time()
print 'call %s() in %fs' % (f.__name__, (t2 - t1))
return r
return fn
@performance
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
有参数的 decorator
允许传入’s’或’ms’:
import time,functools
def performance(unit):
def perf_decorator(f):
@functools.wraps(f)
def wrapper(*args,**kw):
t1 = time.time()
r = f(*args,**kw)
t2 = time.time()
t = (t2 - t1)*1000 if unit == 'ms' else (t2 - t1)
print 'call %s() in %f %s' % (f.__name__,t,unit)
return r
return wrapper
return perf_decorator
@performance('ms')
def factorial(n):
return reduce(lambda x,y:x*y,range(1,n+1))
print factorial(10)
Python内置的functools来复制原函数的属性
偏函数
functools.partial可创建偏函数,可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值,这样,新函数调用的难度就降低了。
import functools
sorted_ignore_case = functional.partial(sorted,cmp=lambda s1,s2: cmp(s1.lower(),s2.lower()))
print sorted_ignore_case(['bob','about','Zoo','Credit'])