Python基础知识十 函数三

1、高阶函数

1.1 高阶函数的概念

  • 接收函数作为参数,或者函数作为返回值的函数就是高阶函数

1.2 高阶函数的特点

  • 特点一 接收一个或多个函数作为参数。
  • 特点二 将函数作为返回值。
    当我们使用一个函数作为参数的时候,实际上是将指定的代码传递给了目标函数。
'''需求:将一个指定列表中的偶数,保存到一个新的列表中返回'''
lst = [1,2,3,4,5,6,7,8,9,10]

def fn1(i):
    if i % 2 == 0:
        return True
    return False

def fn(f,lst):    # 参数lst是要进行筛选的列表
    # 创建一个新的列表
    new_lst = []
    # 对要筛选的列表进行遍历
    for n in lst:
        # 判断n的奇偶
        if f(n):
            new_lst.append(n)
    # 返回新的列表
    return new_lst
print(fn(fn1,lst))

# 运行结果:
# [2, 4, 6, 8, 10]

2、匿名函数

实现需求:将一个指定列表中的能被3整除的数,保存到一个新的列表中返回。可以采用上面高阶函数的方法,如下面的方法一;也可以采用下面的方法二。

'''方法一'''
lst = [1,2,3,4,5,6,7,8,9,10]

def fn1(i):
    if i % 3 == 0:
        return True
    return False

def fn(f,lst):    # 参数lst是要进行筛选的列表
    # 创建一个新的列表
    new_lst = []
    # 对要筛选的列表进行遍历
    for n in lst:
        # 判断n能否被3整除
        if f(n):
            new_lst.append(n)
    # 返回新的列表
    return new_lst
print(fn(fn1,lst))

# 运行结果:
# [3, 6, 9]

'''方法二'''
lst = [1,2,3,4,5,6,7,8,9,10]
r = filter(lambda i : i % 3 == 0,lst)
print(list(r))

# 运行结果:
# [3, 6, 9]

2.1 filter()

filter(参数1,参数2)

  • 参数1:函数对象
  • 参数2:需要过滤的序列(可迭代的对象)
  • 返回值:过滤后的新序列(可迭代的对象)

2.2 lambda函数表达式

  • 匿名函数 — lambda函数表达式,专门用来创建一些简单的函数。
  • 语法:
    • lambda 参数列表 : 返回值
lst = [1,2,3,4,5,6,7,8,9,10]
r = filter(lambda i : i % 3 == 0,lst)
print(list(r))

# 相当于
lst = [1,2,3,4,5,6,7,8,9,10]
def fn(i):
    return i % 3 == 0
r = filter(fn,lst)
print(list(r))
def fn1(a,b):
    return a + b
print(fn1(2,3))
# 运行结果:
# 5

fn2 = lambda a,b : a + b
print(fn2(2,3))
# 运行结果:
# 5

3、闭包

  • 通过闭包可以创建一些只有当前函数能够访问的变量,将一些私有数据藏到闭包中。
  • 形成闭包的条件:
    • 1.函数嵌套
    • 2.将内部函数作为返回值返回
    • 3.内部函数必须使用到外部函数的变量
# 例1
def fn():
    a = 10
    # 在函数内部定义一个函数
    def fn2():
        print('我是fn2',a)
    # 将内部函数fn2作为返回值返回
    return fn2
r = fn()
r()
# 运行结果:
# 我是fn2 10
# 例2
'''求平均数:在一组数据中所有数据之和再除以这组数据的个数
nums = [1,2,3,4,5,6],这组数的平均数=(1+2+3+4+5+6)/6=3.5'''
def avg_fn():
    nums = []
    def fn1(n):
        nums.append(n)
        return sum(nums)/len(nums)
    return fn1
m = avg_fn()
print(m(1))
print(m(2))
print(m(3))
print(m(4))
print(m(5))
print(m(6))
# 运行结果:
# 1.0
# 1.5
# 2.0
# 2.5
# 3.0
# 3.5

关于闭包更详细的介绍,参考:https://blog.csdn.net/u013380694/article/details/90019571

4、装饰器

4.1 装饰器的引入

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

  • 问题一 如果要修改的函数过多,修改起来比较麻烦;
  • 问题二 不方便后期的维护;
  • 问题三 违反开闭原则(ocp):程序的设计思想,要求开发对程序的扩展,要关闭对程序的修改;

4.2 装饰器的使用

'''定义一个函数来对其他的函数进行扩展,使其他的函数可以在执行前打印“开始执行”,执行后打印“执行结束”'''
def add(a,b):
    print('a + b =',a + b)

def start_end(old):
    # 创建一个新的函数
    def new_function(*args,**kwargs):
        print('函数开始执行.....')
        r = old(*args,**kwargs)
        print('函数执行结束.....')
        return r
    # 返回函数
    return new_function

f = start_end(add)
f(123,456)

# 运行结果:
# 函数开始执行.....
# a + b = 579
# 函数执行结束.....

@start_end
def speak():
    print('勇敢地说出自己的想法')

@start_end
def listen():
    print('耐心地倾听他人的声音')

speak()
# 运行结果:
# 函数开始执行.....
# 勇敢地说出自己的想法
# 函数执行结束.....

listen()
# 运行结果:
# 函数开始执行.....
# 耐心地倾听他人的声音
# 函数执行结束.....
  • 上面的例子中,start_end(old)这一类函数我们就称之为装饰器;
  • 通过装饰器(“@start_end”的形式),可以在不修改原来函数的情况下来对函数进行扩展;
  • 在开发中,我们都是通过装饰器来扩展函数的功能。
  • 语法:@×××
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值