Python学习第十课-函数三
一、高阶函数
- 接收函数作为参数
- 将函数作为返回值返回的函数就是⾼阶函数
# 一般函数写法,定义一个函数,然后传入实参
list1 = [1,2,3,4,5,6,7,8,9,10]
def fun(lst):
new_list = []
for i in list1:
if i% 2== 0:
new_list.append(i)
#print(new_list)
return new_list
print(fun(list1)) # 此处也可以理解为高阶函数
'''
[2, 4, 6, 8, 10]
'''
#一般高阶函数 定义fun2(),然后调用fun2的返回值
list1 = [1,2,3,4,5,6,7,8,9,10]
def fun(lst):
def fun2(n):
if n%2==0:
return True
new_list = []
for i in lst:
if fun2(i):
new_list.append(i)
return new_list
print(fun(list1))
'''
[2, 4, 6, 8, 10]
'''
# 高端写法,将函数作为参数使用,同时拆分不同的函数功能,需要使用的时候直接调用即可,大大提高了代码的复用率
list1 = [1,2,3,4,5,6,7,8,9,10]
def fun1(n):
if n % 2 == 0:
return True
def fun2(n):
if n > 5:
return True
def fun3(n):
if n % 2 != 0:
return True
def fun(lst,fn):
new_list = []
for i in lst:
if fn(i):
new_list.append(i)
return new_list
print(fun(list1,fun3))
二、匿名函数
2.1 概念
- python 使用 lambda 来创建匿名函数。
- lambda只是一个表达式,函数体比def简单很多。
- 用于做一些简单的运算,而不用定义函数
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
2.2 语法
- lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]](参数列表):expression(运算)
2.3 示例
# 普通python函数
def func(a, b, c):
return a + b + c
print(func(1, 2, 3))
'''
6
'''
f = lambda a, b, c: a + b + c
print(f(1, 2, 3))
'''
6
'''
res = (lambda a, b: a + b)(1,2)
print(res)
'''
3
'''
2.4 内容扩展
-
将创建好的匿名函数通过一个变量来去接收。
-
使用变量再去调用匿名函数。
# 创建一个匿名函数,作用是实现两个数的和。
lambda num1, num2: num1 + num2
# 使用一个变量来去接收这个匿名函数
res = lambda num1, num2: num1 + num2
# 调用此匿名函数
print(res(10, 20))
'''
30
'''
#该虫用法会出发PEP8:E731 do not assign a lambda expression, use a def不推荐使用
# 匿名函数作为自定义函数的参数传递
def test(a, b, fun):
result = fun(a, b)
print(result)
fun_new = input("请输入一个匿名函数:")
# eval()将字符串str当成有效的表达式来求值并返回计算结果。
fun_new = eval(fun_new)
test(11, 22, fun_new)
"""
请输入一个匿名函数:lambda a,b:a*b
242
"""
三、闭包
- 将函数作为返回值也是⾼阶函数,我们也称为闭包
- 闭包的好处
- 通过闭包可以创建⼀些只有当前函数能访问的变量
- 可以将⼀些私有数据藏到闭包中
- ⾏成闭包的条件
- 函数嵌套
- 将内部函数作为返回值返回
- 内部函数必须要使⽤到外部函数的变量
# 1,函数的嵌套是高阶函数中将一个函数对象作为返回值返回的前提条件
def fun():
def fun1():
pass
return fun1
print(fun()())
# 需求:创建一个函数,赋值一个变量,我要求在这个变量的基础上,每次和不同的数字进行相加
def fun_out(num1):
def fun_inter(num2):
res = num1 + num2
return res
return fun_inter
r = fun_out(1) # fun_out(1)=fun_inter
print(r)
r(2) # fun_out(1)()=fun_inter()
print(r(2))
print(r(3))
'''
<function fun_out.<locals>.fun_inter at 0x7ff56e0941f0>
3
4
'''
# 在闭包中修改外部函数的变量,
def fun_out(num1):
def fun_inter(num2):
nonlocal num1 # 声明此处调用的是外部变量,不是内部变量
num1 = 10
res = num1 +num2
return res
return fun_inter
r = fun_out(1) # fun_out(1)=fun_inter
print(r)
r(2) # fun_out(1)()=fun_inter()
print(r(2))
print(r(3))
四、装饰器
4.1 开闭原则:Open Closed Principle, OCP
- Software entities like classes, modules and functions should be open for extension but closed for modifications.(一个软件实体如类,模块和函数应该对扩展开放,对修改关闭。)
- 软件实体应该对扩展开放,对修改关闭,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。
4.1基础装饰器
def add(a,b):
return a+b
def mul(a,b):
return a*b
def fun(c,d):
print('程序开始执行了')
print(add(c, d))
print('程序执行结束了')
fun(1,2)
'''
程序开始执行了
3
程序执行结束了
'''
4.3 通用装饰器
def fun():
print('我是fun')
def add(a,b):
return a+b
def fun_out(old):
def fun_inner(*args,**kwargs):
print('程序开始执行了')
print(old(*args, **kwargs))
print('程序执行结束了')
return fun_inner
r = fun_out(fun)
r()
'''
程序开始执行了
我是fun
None
程序执行结束了
'''
4.4 语法糖
# # 语法糖: @fun_out
def fun_out(old):
def fun_inner(*args, **kwargs):
print('程序开始执行了')
print(old(*args, **kwargs))
print('程序执行结束了')
return fun_inner
def fun():
print('我是fun')
@fun_out # # r = fun_out(fun) ## #r(1, 2)
def add(a, b):
return a + b
add(1, 2)
五、PEP8规范
六、作业
请使用装饰器实现一存在函数的执行所花费的时间
.time模块
# @author:mianhua
# @Time:2021/5/6下午11:45
# @File:作业.py
# @Descriptions:
# 引入一个time模块,来统计程序执行时间
from time import *
# time()函数可以获取当前时间,返回单位是秒
def fun_out(old):
def fun_inner(*args, **kwargs):
begin = time() # 设置开始运行时间
old(*args, **kwargs)
end = time() # 设置结束时间
print("程序运行时间为:{}秒".format(end - begin))
return fun_inner
def fun(n): # 求第一天共摘了多少桃子 fun(1)
if n == 100: # 基准条件
return 1
else:
return (fun(n + 1) + 1) * 2 # 递归条件:
@fun_out
def show_print():
for i in range(100, 1, -1):
print("第{}天,还剩{}个桃子".format(i, fun(i)))
print("第1天一共有{}个挑子".format(fun(1)))
show_print()
'''
第100天,还剩1个桃子
第99天,还剩4个桃子
第98天,还剩10个桃子
第97天,还剩22个桃子
第96天,还剩46个桃子
第95天,还剩94个桃子
第94天,还剩190个桃子
第93天,还剩382个桃子
第92天,还剩766个桃子
第91天,还剩1534个桃子
第90天,还剩3070个桃子
第89天,还剩6142个桃子
第88天,还剩12286个桃子
第87天,还剩24574个桃子
第86天,还剩49150个桃子
第85天,还剩98302个桃子
第84天,还剩196606个桃子
第83天,还剩393214个桃子
第82天,还剩786430个桃子
第81天,还剩1572862个桃子
第80天,还剩3145726个桃子
第79天,还剩6291454个桃子
第78天,还剩12582910个桃子
第77天,还剩25165822个桃子
第76天,还剩50331646个桃子
第75天,还剩100663294个桃子
第74天,还剩201326590个桃子
第73天,还剩402653182个桃子
第72天,还剩805306366个桃子
第71天,还剩1610612734个桃子
第70天,还剩3221225470个桃子
第69天,还剩6442450942个桃子
第68天,还剩12884901886个桃子
第67天,还剩25769803774个桃子
第66天,还剩51539607550个桃子
第65天,还剩103079215102个桃子
第64天,还剩206158430206个桃子
第63天,还剩412316860414个桃子
第62天,还剩824633720830个桃子
第61天,还剩1649267441662个桃子
第60天,还剩3298534883326个桃子
第59天,还剩6597069766654个桃子
第58天,还剩13194139533310个桃子
第57天,还剩26388279066622个桃子
第56天,还剩52776558133246个桃子
第55天,还剩105553116266494个桃子
第54天,还剩211106232532990个桃子
第53天,还剩422212465065982个桃子
第52天,还剩844424930131966个桃子
第51天,还剩1688849860263934个桃子
第50天,还剩3377699720527870个桃子
第49天,还剩6755399441055742个桃子
第48天,还剩13510798882111486个桃子
第47天,还剩27021597764222974个桃子
第46天,还剩54043195528445950个桃子
第45天,还剩108086391056891902个桃子
第44天,还剩216172782113783806个桃子
第43天,还剩432345564227567614个桃子
第42天,还剩864691128455135230个桃子
第41天,还剩1729382256910270462个桃子
第40天,还剩3458764513820540926个桃子
第39天,还剩6917529027641081854个桃子
第38天,还剩13835058055282163710个桃子
第37天,还剩27670116110564327422个桃子
第36天,还剩55340232221128654846个桃子
第35天,还剩110680464442257309694个桃子
第34天,还剩221360928884514619390个桃子
第33天,还剩442721857769029238782个桃子
第32天,还剩885443715538058477566个桃子
第31天,还剩1770887431076116955134个桃子
第30天,还剩3541774862152233910270个桃子
第29天,还剩7083549724304467820542个桃子
第28天,还剩14167099448608935641086个桃子
第27天,还剩28334198897217871282174个桃子
第26天,还剩56668397794435742564350个桃子
第25天,还剩113336795588871485128702个桃子
第24天,还剩226673591177742970257406个桃子
第23天,还剩453347182355485940514814个桃子
第22天,还剩906694364710971881029630个桃子
第21天,还剩1813388729421943762059262个桃子
第20天,还剩3626777458843887524118526个桃子
第19天,还剩7253554917687775048237054个桃子
第18天,还剩14507109835375550096474110个桃子
第17天,还剩29014219670751100192948222个桃子
第16天,还剩58028439341502200385896446个桃子
第15天,还剩116056878683004400771792894个桃子
第14天,还剩232113757366008801543585790个桃子
第13天,还剩464227514732017603087171582个桃子
第12天,还剩928455029464035206174343166个桃子
第11天,还剩1856910058928070412348686334个桃子
第10天,还剩3713820117856140824697372670个桃子
第9天,还剩7427640235712281649394745342个桃子
第8天,还剩14855280471424563298789490686个桃子
第7天,还剩29710560942849126597578981374个桃子
第6天,还剩59421121885698253195157962750个桃子
第5天,还剩118842243771396506390315925502个桃子
第4天,还剩237684487542793012780631851006个桃子
第3天,还剩475368975085586025561263702014个桃子
第2天,还剩950737950171172051122527404030个桃子
第1天一共有1901475900342344102245054808062个挑子
程序运行时间为:0.001051187515258789秒
'''
#感觉猴子可能会撑死。。。不对地球可能放不下这么多桃子...