例子 将 lst = [1,2,3,4,5,6,7,8,9,10] 中所有的偶数,保存到一个新的列表中返回
lst = [1,2,3,4,5,6,7,8,9,10] # 定义一个函数 用来将指定列表中所有的偶数,保存到一个新的列表中返回 def fn(lst): # 参数 要进行筛选列表 # 创建一个新的列表 new_lst = [] for n in lst: # 判断n的奇偶 if n % 2 == 0: new_lst.append(n) return new_lst print(fn(lst)) 结果 [2, 4, 6, 8, 10]引出高阶函数
满足2个条件任意一个都是高阶函数:
接收一个或多个函数作为参数 将函数作为返回值返回
例子:将 lst = [1,2,3,4,5,6,7,8,9,10] 中所有的奇数,保存到一个新的列表中返回
lst = [1,2,3,4,5,6,7,8,9,10] # 定义一个函数 用来将指定列表中所有的偶数,保存到一个新的列表中返回 def fn(lst): # 参数lst 要进行筛选列表 # 定义一个函数 用来测偶数 def fn2(i): if i % 2 == 0: return True # 创建一个新的列表 new_lst = [] for n in lst: # 添加 if not fn2(n): new_lst.append(n) return new_lst print(fn(lst)) 结果 [1, 3, 5, 7, 9]例子:将 lst = [1,2,3,4,5,6,7,8,9,10] 中大于5的数,保存到一个新的列表中返回
lst = [1,2,3,4,5,6,7,8,9,10] # 定义一个函数 用来将指定列表中所有的偶数,保存到一个新的列表中返回 def fn(lst): # 参数lst 要进行筛选列表 # 定义一个函数 用来检测是否大于5 def fn3(i): if i > 5: return True return False # 创建一个新的列表 new_lst = [] for n in lst: # 添加 if fn3(n): new_lst.append(n) return new_lst print(fn(lst)) 结果 [6, 7, 8, 9, 10] 但是上面两个例子,写死了。下面的可以调用不同的函数当我们使用一个函数作为参数时,实际上我们就是将指定的代码传递给了目标函数 lst = [1,2,3,4,5,6,7,8,9,10] # 定义一个函数 用来测偶数 def fn2(i): if i % 2 == 0: return True # 定义一个函数 用来检测是否大于5 def fn3(i): if i > 5: return True return False # 定义一个函数 用来检测是否3的倍数 def fn4(i): if i % 3 == 0: return True return False def fn(func,lst): # 参数lst 要进行筛选列表 # 创建一个新的列表 new_lst = [] for n in lst: # 添加 if func(n): new_lst.append(n) return new_lst print(fn(fn4,lst)) 调用fn4结果 [3, 6, 9]通过闭包可以换创建一些只有当前函数才能访问的对象,还可以将一些私有的数据藏到闭包中
# 将函数作为返回值返回,我们也称为闭包 def fn(): a = 10 # 在函数内部定义一个函数 def fn2(): print('我是fn2',a) # 将内部函数作为返回值返回 return fn2 # 返回的是函数对象 # r是一个函数,是调用fn()后返回的函数,这个函数是在fn内部定义,并不是全局函数 r = fn() # 值是空 不是全局函数 r() print(a) 结果 我是fn2 10 NameError: name 'a' is not defined # # 求多个数的平均值 # nums = [50,20,60,10,80] # # # sum() 用来求一个列表中元素之和 # print(sum(nums)/len(nums)) nums = [] # 是全局变量 # 定义一个函数,实现就算平均值 def average(n): # 将n添加到列表当中 nums.append(n) # 求平均值 return sum(nums)/len(nums) print(average(10)) print(average(5)) 结果 10.0 7.5采用闭包的方式
def make_average(): nums = [] # 是局部变量 只能内部看到 # 定义一个函数,实现就算平均值 def average(n): # 将n添加到列表当中 nums.append(n) # 求平均值 return sum(nums)/len(nums) return average print(make_average()) a = make_average() print(a(10)) print(a(5)) 结果 <function make_average.<locals>.average at 0x000001AA3E100E18> 10.0 7.5形成闭包的条件:
函数嵌套 将内部函数作为返回值返回 内部函数必须使用到外部函数的变量
当不希望别人去修改的时候,使用闭包
我们可以通过修改函数中的代码来完成装饰,但是会产生一些问题:
修改的函数很多 不方便后期的维护 会违反开闭原则(ocp) 程序设计 要求对程序的扩展,但是要关闭对程序的修改
不修改原函数,来对函数进行扩展
# 不修改原函数,来对函数进行扩展 def fn(): print('我是fn函数') # 定义一个函数 对fn进行扩展 def fn2(): print('函数开始执行') fn() print('函数执行结束') fn2() 结果 函数开始执行 我是fn函数 函数执行结束 # 求任意两个数的和 def add(a,b): return a + b # 求任意两个数的乘积 def mul(a,b): return a * b r = add(1,20) def new_add(a,b): print('函数开始执行') r = add(a,b) print('函数执行结束') return r result = new_add(1,2) print(result) 结果 函数开始执行 函数执行结束 3 上述较为麻烦因此需要通用的方式了对函数进行扩展在Python的函数中偶尔会看到函数定义的上一行有@functionName的修饰,当解释器读到@的这样的修饰符之后,会先解析@后的内容,直接就把@下一行的函数或者类作为@后边的函数的参数,然后将返回值赋值给下一行修饰的函数对象。 比如: @a @b def c(): … python会按照自下而上的顺序把各自的函数结果作为下一个函数(上面的函数)的输入,也就是a(b(c())) ———————————————— 版权声明:本文为博主「saberpan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/saberpan/article/details/85258781
‘@’引用已有的函数,对下面的函数进行修饰。引用函数必须放在修饰函数的上面,引用函数的返回值,返回给被修饰的函数 https://www.cnblogs.com/liangxiyang/p/11200476.html
例子
def fn(): print('我是fn函数') def add(a,b): return a + b def start_end(old): # 类似于start_end(old)就是装饰器 # 用来对其他的函数进行扩展 扩展函数执行的时候打印 开始执行 执行后打印 执行结束 # 参数old---要扩展的函数对象 # 创建一个函数 def new_function(*args,**kwargs): # 参数装包 转换为一个个元组或者字典 # *args用来接收所有的位置参数,,**kwargs用来接收所有的关键字参数 print('开始执行') # 要调用被扩展的函数 result = old(*args,**kwargs) # 把位置参数拆包,放到元组进去,,或者把关键字 转换字典 传进去 print('执行结束') return result # 返回新函数 return new_function f = start_end(add) @start_end def speak(): print('大家加油') speak() 结果 开始执行 大家加油 执行结束