高阶函数
以函数作为参数或者以函数作为返回值返回的函数
lst = [1,2,3,4,5,6,7,8,9,10]
def fn2(i): #求偶数函数
if i % 2 == 0:
return True
def fn(func,l): #高阶函数(将函数作为参数)
lst2=[]
for n in l:
if func(n):
lst2.append(n)
return lst2
print(fn(fn2,lst))
闭包
高阶函数的第二种,将函数作为参数返回
通过闭包可以创建一些只有当前函数能够访问的变量
可以将一些私有的重要的放到闭包当中(PS:相当于自我封装,只能通过内部访问来获取)
闭包形成条件
1.嵌套函数(在函数内再定义一个函数)
2.将内部函数作为返回值返回
3.内部函数使用外部函数的变量
#fn()函数内的代码块,即形成闭包,外部无法获取到fn()内的a值,只有fn2()内能够获取到
def fn():
a = 10
# 在函数内部在定义一个函数
def fn2():
print('我是fn2',a)
# 将内部函数fn2作为返回值返回
return fn2
r=fn()
print(r) #我是fn2 10 None(因为fn2()没有返回值)
print(a) # NameError: name 'a' is not defined
a=20
print(r) #我是fn2 10 None 函数外部修改a的值不影响函数内部的变量,因为不是同一个对象
匿名函数
语法:lambda 参数列表 : 返回值
主要用来代替一些简单的逻辑函数,并且只会使用一次,随时使用完随时被回收
def fn5(a,b):
return a + b
print(fn5(1,2))
#上述简单逻辑函数可以被匿名函数lambda表示
fn5 = lambda a,b : a + b
print(fn5) #<function <lambda> at 0x0000021758F52F28> 返回值是一个名为lambda的匿名函数
print(fn5(5,6)) #11
#或者lambda后直接跟实参值
fn6 = (lambda a,b : a + b)(10,50)
print(fn6) #60
filter()函数
filter() 就是一个高阶函数 它需要将别的函数作为参数来传递,可以将我们的可迭代对象进行一个过滤,返回值是个可迭代的对象
lst = [1,2,3,4,5,6,7,8,9,10]
def fn4(i):
if i % 3 == 0:
return True
return False
# filter(fn4,lst) 等价于 filter(lambda i : i % 3 == 0,lst)
装饰器的引入
概念
扩展函数内容
装饰器产生的原因
- 如果要修改的函数过多,修改起来会非常麻烦
- 不方便后期维护
- 这样做会违反ocp原则(开闭原则) 要求开放对程序的扩展,要求关闭对程序的修改
def fn():
print('我是fn函数')
# 定义一个新的函数 就是对原函数进行的扩展
def fn2():
print('函数开始执行')
fn()
print('函数执行结束')
装饰器的使用
作用
1.像类似于start_end(old)这种函数我们就称之为装饰器
2.通过装饰器可以在不修改原来的函数的情况下对函数进行扩展
3.在开发中,我们都是通过装饰器来扩展函数的功能的
# 定义一个函数 就是对其他函数进行扩展的 扩展的功能一个 是打印函数开始执行 一个是打印函数执行结束
def start_end(old): #old参数为扩展之前的函数
# 内部创建了一个函数
def new_function(*args,**kwargs): #针对参数的可扩展性
print('函数开始执行')
r = old(*args,**kwargs)
print('函数执行结束')
# 返回函数的执行结果
return r
# 返回新的函数
return new_function #返回值为扩展之后的函数对象
def fn():
print('我是fn函数')
def add(a,b):
r = a + b
return r
f = start_end(fn)
print(f())
f2 = start_end(add)
print(f2(13,46))
使用方法
在定义完装饰器后,在扩展前的函数前加上@装饰器函数名
@start_end
def speak():
print('Hello World')
speak()