Python 入门之路(10)

高阶函数

特点1:接收一个或多个函数作为参数;
特点2:将函数作为返回值返回

当使用函数作为参数时,实际上是将指定的代码返回

# 将一直指定列表中的偶数,保存到一个新的列表中返回
lst = [1,2,3,4,5,6,7,8,9,10]
def fn(lst):
    # 参数lst 要进行帅选的列表
    # 创建一个新的列表
    new_lst = []
    # 遍历列表
    for n in lst:
        # 判断奇偶
        if n % 2 == 0
            new_lst.append()
    return new_lst
lst = [1,2,3,4,5,6,7,8,9,10]
def fn(lst):
    # 定义一个函数用来检测任意数的偶数
    def fn2(i):
        if i % 2 == 0
        return True
    # 参数lst 要进行帅选的列表
    # 创建一个新的列表
    new_lst = []
    # 遍历列表
    for n in lst:
        # 判断奇偶
        if fn2(n):
            new_lst.append(n)
    return new_lst
def fn2(i):
        if i % 2 == 0
        return True

def fn3(i):
        if i > 5 :
        return True
        
def fn(func,lst):
    # 参数lst 要进行帅选的列表
    # 创建一个新的列表
    new_lst = []
    # 遍历列表
    for n in lst:
        # 调用奇偶
        if func(n):
            new_lst.append(n)
    return new_lst

匿名函数

filter(func,lst)
参数1:函数;参数2:需要过滤的序列; 返回值,过滤后的 新的序列

lst = [1,2,3,4,5,6,7,8,9,10]

def fn4(i):
    if i % 3 == 0:
        return True
    return False
print(filter(fn4,lst))
print(lst(filter(fn4,lst))) # [3,6,9]

匿名函数 lambda函数表达式
lambda 函数表达式就是专门用来创建一些简单的函数
语法: lambda 参数列表 :返回值

# print(lambda a,b : a + b) # 返回是一个函数对象
print((lambda a,b : a + b)(50,60)) 
fn = lambda a,b : a + b
print(fn(50,60))

r = filter(lambda i: i % 3 == 0 ,lst)
print(list(r))

闭包

将函数作为返回值也是高阶函数
通过闭包可以创建一些只有当前函数才能访问的变量,可以将一些私有数据存到闭包

形成闭包的条件
1:函数嵌套
2:将内部函数作为返回值返回
3:内部函数必须使用带外部函数的变量

def fn():
    a = 10
    def fn2():
        print('我是fn2', a)
    #将函数内部函数fn2作为返回值返回
    return fn2
fn() # fn2
print(fn()) # 相当于pirnt(fn2) ,输出的是一个函数对象
r = fn()
r() # 我是fn2 10    调用这个函数
# 求平均数
# 定义一个函数求平均数
num2 = [] # 在全局中容易被修改
def avg(n):
    nums2.append(n)
    return sum(nums2)/len(nums2)
print(avg(10)) # 10
print(avg(20)) # 15
def make_fn():
    num2 = [] # 在闭包内中外部访问不到
    def avg(n):
        nums2.append(n)
        return sum(nums2)/len(nums2)
    return avg
print(make_fn(10)) # 10
print(make_fn(20)) # 20

装饰器的引入

我们可以通过修改函数中的代码来完成修饰,但会产生一些问题

  1. 要修改的函数过多,修改麻烦
  2. 不方便后期维护
  3. 违反ocp原则(开闭原则) 程序的设计思路 要求开放对源程序的扩展,关闭对源程序的修改
# 求任意两个数的和
def add(a,b):
    # 修饰内容
    print('函数开始计算')
    print('函数计算结束')
    return a + b
# 求任意两个数的积
def mul(a,b):
    print('函数开始计算')
    print('函数计算结束')
    return a * b
#希望在不修改原函数的前提下,来增加函数扩展功能
def fn():
    print('我是fn函数')
# 创建一个函数对原函数进行扩展
def fn2():
    print('函数开始执行......')
    fn()
    print('函数执行结束......')
def new_add(a,b):
    print('函数开始执行......')
    r = add(a,b)
    print('函数执行结束......')
    return r
    
fn()
fn2() #实际上是调用fn
print(r) # 实际上是调用add

装饰器的使用

start_end()这一类函数称之为装饰器,通过装饰器,可以在不修改原函数的情况下对函数进行扩展
在开发中,我们都是通过装饰器来对原函数进行扩展

# 创建一个函数对原函数进行扩展,使其他函数在执行前打印开始执行,执行后打印执行结束
def fn():
    # 参数old是要扩展的函数
    print('我是fn函数')
    
def add(a,b):
    return a + b
    
def start_end(old_func):
   # 参数old是要扩展的函数
   # 创建一个新的函数
   def new_function(*args,**kwargs):
       print('函数开始执行......')
       old_func(*args,**kwargs)
       print('函数执行结束......')
   # 返回函数
   return new_function
   
f = start_end(fn)
f()
f2 = start_end(add)
print(f2(1,2))

# f2 = start_end()
# print(f)
# print(f2) #两个是不同的函数
@start_end
def speak():
   print('同学们好好复习!!!')
   
speak()