Python基础课--第十一节 函数3

1 高阶函数

例子 将 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]

2 闭包

# 将函数作为返回值返回,我们也称为闭包

def fn():

    # 在函数内部定义一个函数
    def fn2():

        print('我是fn2')

    # 将内部函数作为返回值返回
    return fn2  # 返回的是函数对象

print(fn())
结果
<function fn.<locals>.fn2 at 0x000001717CAD5620>
# 将函数作为返回值返回,我们也称为闭包

def fn():

    # 在函数内部定义一个函数
    def fn2():

        print('我是fn2')

    # 将内部函数作为返回值返回
    return fn2  # 返回的是函数对象
# r是一个函数,是调用fn()后返回的函数,这个函数是在fn内部定义,并不是全局函数
r = fn()
r()    # 调用后值是空

print(r())
结果
我是fn2
我是fn2
None

通过闭包可以换创建一些只有当前函数才能访问的对象,还可以将一些私有的数据藏到闭包中

# 将函数作为返回值返回,我们也称为闭包

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

形成闭包的条件:

函数嵌套
将内部函数作为返回值返回
内部函数必须使用到外部函数的变量

当不希望别人去修改的时候,使用闭包

3 装饰器的引入

# 求任意两个数的和
def add(a,b):
    print('开始计算')
    print('计算结束')
    return a + b
# 求任意两个数的乘积
def mul(a,b):

    return a * b

r = add(1,20)
print(r)
结果
开始计算
计算结束
21
  • 我们可以通过修改函数中的代码来完成装饰,但是会产生一些问题:

    修改的函数很多
    不方便后期的维护
    会违反开闭原则(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
  • 上述较为麻烦
  • 因此需要通用的方式了对函数进行扩展

4 装饰器的使用

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)

r = f(111,222)
print(r)
结果
开始执行
执行结束
333
  • start_end(old) 类似于这样的函数其实就是一个装饰器,通过装饰器可以在不修改原函数的情况下对函数进行扩展,在开发当中,都是通过装饰器来扩展函数的功能
  • @

在Python的函数中偶尔会看到函数定义的上一行有@functionName的修饰,当解释器读到@的这样的修饰符之后,会先解析@后的内容,直接就把@下一行的函数或者类作为@后边的函数的参数,然后将返回值赋值给下一行修饰的函数对象。
比如:
@a
@b
def c():

python会按照自下而上的顺序把各自的函数结果作为下一个函数(上面的函数)的输入,也就是a(b(c()))
————————————————
版权声明:本文为CSDN博主「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()
结果
开始执行
大家加油
执行结束
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值