1 基本概念
高阶函数: 接收函数作为参数,或者将函数作为返回值返回的函数就是高阶函数
(以下代码均由python 3.8演示)
# 高阶函数实例一 将函数作为一个参数
def fn(a,b):
print("%d+%d=%d"%(a,b,a+b))
def fn1(a,b,func):
func(a,b)
---------------------------------------------
fn1(2,3,fn) #将fn函数对象传入fn1
'''
运行结果:
2+3=5
'''
# 高阶函数实例二 函数作为返回值
#下面两个代码功能相同,注意fn()返回值和print()区别
#返回值为函数
def fn(a,b):
print("%d+%d=%d"%(a,b,a+b))
def fn1(a,b,func):
func(a,b)
print("%d+%d=%d" % (a, b, a + b))
return func
s=fn1(2,3,fn) #经fn1返回,此一步相当于s=fn
s(7,8) #相当于fn(7,8)
'''
运行结果:
2+3=5
2+3=5
7+8=15
'''
---------------------------------------------
#返回值为函数
def fn(a,b):
return("%d+%d=%d" % (a, b, a + b)) #与上一个代码,此处为返回值
def fn1(a,b,func):
x=func(a,b) #返回值需要有接收,否则返回无意义
print(x) #返回并输出返回值
print("%d+%d=%d" % (a, b, a + b))
return func
s=fn1(2,3,fn) #经fn1返回,此一步相当于s=fn
print(s(7,8)) #相当于print(fn(7,8)),因此此时fn()结果为返回,
#所以需要使用print()输出结果
'''
运行结果:
2+3=5
2+3=5
7+8=15
'''
常用内置高阶函数:
参考资料:Python之高阶函数 来源:优快云
- map(): 接收一个函数 f 和一个或多个序列list,并通过把函数 f 依次作用在 序列list 的每个元素上,python 2 返回一个新的 list ,python 3返回一个迭代器
#map()
s=[1,2,3,4,5]
def f(x):
return(x+x)
w=map(f,s)
print(w,type(w))
for i in w:
print(i,end=' ')
'''
运行结果:
2+3=5
2+3=5
7+8=15
'''
- filter(): 用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。( Pyhton2.7 返回列表,Python3.x 返回迭代器对象)
s=(1,2,3,4,5)
def f(x):
return(x>2)
w=filter(f,s)
print(w,type(w))
for i in w:
print(i)
'''
运行结果:
3
4
5
'''
- reduce(): reduce()函数接收的参数和 map()类似,但是行为不同。reduce() 函数会对参数序列中元素进行累积。reduce()传入的函数 f 必须接收两个参数,用传给 reduce 中的函数 f(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 f 函数运算,最后得到一个结果
from functools import reduce # python 3 以上版本已经把reduce()从全局变量中移除至functools
s=(1,2,3,4,5)
def f(x,y):
return(x+y)
w=reduce(f,s)
print(w,type(w))
'''
运行结果:
15 <class 'int'>
'''
- sorted(): list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作
s=(34,2,1,7,5)
b=sorted(s,reverse=True)
print(b)
'''
运行结果:
[34, 7, 5, 2, 1]
'''
-
lambda():
参考资料:
python高阶函数 来源:优快云
Python3 sorted() 函数 来源:菜鸟教程- 语法: lambda 参数列表 : 返回值
- lambda只是一个表达式,函数体比def简单很多
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去
- lambda函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数
- lambda返回的是函数对象(构建的是一个函数对象),所以需要定义一个变量去接收
#实例1
print((lambda a,b : a + b)(1,2)) #运行结果:3
#------------------------------------
#实例2
def test(a,b,func):
result = func(a,b)
return result
num = test(11,22,lambda x,y:x+y)
print(num)
#运行结果:33
#-----------------------------------------
#实例三
d1 = [{'name':'alice', 'score':38}, {'name':'bob', 'score':18}, {'name':'darl', 'score':28}, {'name':'christ', 'score':28}]
l = sorted(d1, key=lambda x:(x['score'], x['name']))
print(l)
'''
运行结果:
[{'name': 'bob', 'score': 18}, {'name': 'christ', 'score': 28}, {'name': 'darl', 'score': 28}, {'name': 'alice', 'score': 38}]
'''
2 闭包
参考资料:
理解Python闭包概念 来源:博客园
python中闭包详解 来源:博客园
- 闭包: 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包
- 闭包的好处:
- 可创建一些只有当前函数才能访问的变量
- 可以将一些私有数据藏到闭包中
- 形成闭包的条件:
- 函数套嵌
- 内部函数作为返回值返回
- 内部函数用到外部函数变量
#实例一 一个闭包实例对其自由变量的修改会被传递到下一次该闭包实例的调用
def outer(x):
def inner(y):
nonlocal x
x+=y
return x
return inner
a = outer(10)
print(a(1))
print(a(3))
'''
运行结果:
11
14 #a(1)对x的修改结果保存到a(2)
'''
#---------------------------------------------
#实例二 闭包中的引用的自由变量只和具体的闭包有关联,闭包的每个实例引用的自由变量互不干扰
def outer_func():
loc_list = []
def inner_func(name):
loc_list.append(len(loc_list) + 1)
print ('%s list = %s' %(name, loc_list))
return inner_func
func_0 = outer_func()
func_0('func_0')
func_0('func_0')
func_0('func_0')
func_1 = outer_func()
func_1('func_1')
func_0('func_0')
func_1('func_1')
'''
运行结果:
func_0 list = [1]
func_0 list = [1, 2]
func_0 list = [1, 2, 3]
func_1 list = [1] #func_1 与 func_0 引用的变量互不干扰
func_0 list = [1, 2, 3, 4]
func_1 list = [1, 2]
'''
3 装饰器
参考资料:
Python装饰器的通俗理解
一文看懂Python系列之装饰器(decorator)(工作面试必读)
- 装饰器: 装饰器本质上是一个嵌套函数,它接受被装饰的函数(func)作为参数,并返回一个包装过的函数,可以在不改变被装饰函数的代码的情况下给被装饰函数或程序添加新的功能
- 作用:
- 在不修改原函数的情况下对函数进行扩展
- 在开发中,通过装饰器扩展函数功能
#实例一
def add(a,b):
r = a + b
return r
def start_end(old):
def new_function(*args,**kwargs):
print('开始计算.....')
# 调用被扩展的函数
result = old(*args,**kwargs)
print('执行结束.....')
return result
return new_function
f = start_end(add)
r = f(1,2)
print(r)
print('-----------------')
@start_end
def speak():
print('biu biu!!!')
speak()
'''
运行结果:
开始计算.....
执行结束.....
3
-----------------
开始计算.....
biu biu!!!
执行结束.....
'''
#-------------------------------
# 实例二
def t1():
return('原函数')
def outer(x):
def inner(*args,**kwargs):
print('内层函数啥也不做')
r = x()
return r
return inner
a = outer(t1)
print(a())
print('-----------------')
@outer
def t2():
return("新函数")
print(t2())
'''
运行结果:
内层函数啥也不做
原函数
-----------------
内层函数啥也不做
新函数
'''
#-------------------------------
#实例三
def hint(func):
def wrapper():
print('{} is running'.format(func.__name__))
return func()
return wrapper
@hint
def hello():
print("Hello!")
hello()
'''
运行结果:
hello is running
Hello!
'''
特别提醒:
- 实例四 注释部分只是个人理解,旨在自己能更好的记住装饰器用法,请各位同为新人的朋友谨慎对待此四行注释,正确与否有待指正
- 同时,若有错误,欢迎各位前辈指正,以防止此注释产生误导作用,在此感谢各位前辈
#实例四 带参数的修饰器
def outer1(cs): #第一层接收参数
def outer2(fun): #第二层接收外部函数
def inner(): #第三层调用接收的函数
print('%s啥也不做'%(cs)) #用装饰器时,其实替换了原本代码的函数,因此本人没有定义原来函数
r = fun()
return r
return inner
return outer2
@outer1(cs='张三')
def t2():
return("新函数")
print(t2())
'''
运行结果:
张三啥也不做
新函数
'''