1.高阶函数
- 接收函数作为参数
# 高阶函数——接收函数作为参数,或接收函数作为返回值
# 定义一个函数将列表中所有的偶数保存到一个新的列表中
lst1 = [1, 2, 3, 4, 5, 6, 7, 8]
# 高阶函数
# 函数作为参数——此时就是将一段代码传递到函数中啦
# 检查奇偶、是否大于3
def fn1(i):
if i % 2 == 0:
return True
def fn2(i):
if i % 2 != 0:
return True
def fn3(i):
if i > 3:
return True
def fn(func, lst):
new_list = []
# 遍历
for i in lst:
# 判断 调用函数——注意这里时函数调用不是函数对象
if func(i):
new_list.append(i)
# 返回
return new_list
s = fn(fn3, lst1)
print(s)
- 将函数作为返回值返回
1.1 匿名函数
'''
filter(func, lst)可以从序列里过滤出符合条件的元素,保存到一个新的序列中
参数一func 这是一个函数对象,根据这个函数来过滤
参数二lst 这是一个序列,是需要进行过滤的对象
返回值 这是过滤后产生的新序列
'''
lst = [1, 2, 3, 6, 5, 9, 12]
def fn1(i):
if i % 3 == 0:
return True
return False
# def fn(func, lst):
# new_lst = []
# for i in lst:
# if fn1(i):
# new_lst.append(i)
# return new_lst
# print(fn(fn1, lst))
s = list(filter(fn1, lst))
print(s)
# 匿名函数 lambda 函数表达式
# lambda函数表达式专门用来创建一些简单的函数,是函数的另一种表达方式
# 语法:lambda 参数列表:返回值
# 常规函数
def fm(a, b):
return a + b
# 匿名函数
fm1 = lambda a,b: a + b
print(s(1, 2))
2.闭包
- 将函数作为返回值返回的高阶函数我们又称之为闭包
# 高阶函数
# 以函数作为返回值,又称为闭包
# 通过闭包可以创建一些只有当前函数可以访问的变量 a
# 可以将一些私有的变量藏到闭包中
def fn():
a = 123
def fn1():
print('我是fn1...', a)
return fn1
s = fn()
print(s) # <function fn.<locals>.fn1 at 0x0000000002880620>
print(s()) # 我是fn1... 123
# None
s() # 我是fn1... 123
print(a) # NameError: name 'a' is not defined
-
闭包的好处
。通过闭包可以创建一些只有当前函数可以访问的变量
。可以将一些私有数据藏到闭包中 -
形成闭包的条件
。函数嵌套
。将内部函数作为返回值返回
。内部函数必须要使用到外部函数的变量
# 求列表中元素的平均值
# nums = [4, 4, 6, 3, 7, 8, 9]
# print(sum(nums) / len(nums))
# 定义一个函数求平均值
# 我不成熟的写法
# nums = [4, 4, 6, 3, 7, 8, 9]
# def average(nums):
#
# return sum(nums) / len(nums)
#
# print(average(nums))
# 老师的写法
# nums = [] 写在全局时容易被修改
# 闭包三条件,缺一不可:
# 闭包——函数嵌套
# 闭包——内部函数作为返回值
# 闭包——内部函数用到外部函数的变量
def make_average():
nums = []
def average(n):
nums.append(n)
return sum(nums) / len(nums)
# print(average(10)) # 10.0
# print(average(5)) # 7.5
return average
fn = make_average()
print(fn(10)) # 10.0
print(fn(5)) # 7.5
3.装饰器的引入
- 我们可以直接修改函数中的代码来满足要求,但是往往伴随以下问题:
。如果修改的函数比较多,就比较麻烦
。不方便后期维护
。违反开闭原则ocp(程序设计要求开发对程序的扩展,关闭对程序的修改)
4.装饰器的使用
- 通过装饰器可以在不修改原来函数的情况下,对函数进行修改
- 在开发中,我们都是通过装饰器来扩展函数的功能的
# 装饰器 —— 类似于start_end(old)这种不用对原函数修改就能对其功能进行扩展的函数
def start_end(old):
# 创建一个新的函数
def new_function(*args,**kwargs):
print('开始执行..')
# fn()
r=old(*args,**kwargs)
print('执行结束..')
return r
return new_function
# 装饰器的写法
@start_end
def speak():
print('同学们好好复习啊')
speak()
@start_end
def fn():
print('我是fn函数')
fn()
@start_end
def add(a,b):
r = a+b
return r
r=add(123,123)
print(r)