自学内容网 自学内容网

Python高阶函数以及装饰器

1、闭包函数

如果内函数使用了外函数的局部变量,并且外函数把内函数返回的过程就叫闭包

形成闭包的条件:

1.函数嵌套

2.将内函数作为返回值返回

3.内函数必须使用外函数的局部变量

def out_fun(x):
    def in_fun(y):
        return y**x
    return in_fun
print(out_fun(2)(3))

2、lambda匿名函数

没有名字的函数,一般函数体只有一条语句,一个返回值,用于实现简单功能

代码示例:

print((lambda x:x*x)(9))#9的平方
fun1=lambda x:x*2
print(fun1(88))#88的二倍
fun2=lambda :print("我是匿名函数")
fun2()
fun3=lambda :3
print(fun3)#返回的<function <lambda> at 0x0000019CC46F9940>
print(fun3())#返回值是3
fun4 = lambda *num : sum(num)
print(fun4(1,2,3,4,5))
fun5 = lambda **stus : stus
print(fun5(zhangsan=18, lisi=20, wangwu=19))
fun6 = lambda a,b=1 : a+b
print(fun6(3))
print(fun6(3,8))
# 使用匿名函数接收两个参数a和b,返回a、b的较大值
fun7 = lambda a, b: max(a,b)
print(fun7(10,20))
# python中的三元运算符
# 结果1 if 条件 else 结果2
fun8 = lambda a, b : a if a>b else b
print(fun8(13,10))

lambda函数的特性

  1. lambda函数是匿名的,即它是没有名字的函数,并且自带return。
  2. lambda函数可以使用任意数量的参数,但只能包含一个表达式。
  3. lambda函数返回一个值,这个值就是表达式的结果。
  4. lambda函数的生命周期很短,调用后立即被回收。

3、高阶函数

1. map()将函数应用于每个元素

map() 用于将一个指定的函数应用到可迭代对象的每个元素上,返回一个 迭代器,其元素是原始可迭代对象的每个元素经过函数处理后的结果。

语法

map(function, iterable, ...)
  • function:一个函数,它接受可迭代对象的元素作为输入,并返回处理后的结果。

  • iterable:一个可迭代对象,如列表、元组等。如果有多个可迭代对象,它们会逐一传递给 function

示例:将列表中的每个数字平方

lst = [1, 2, 3, 4] 
result = map(lambda x: x ** 2, lst) 
print(list(result)) # 输出: [1, 4, 9, 16]
  • map() 的特点:它逐一处理每个元素,并返回一个新的迭代器,而不是修改原始列表。

2. filter()过滤符合条件的元素

filter() 用于根据指定条件从可迭代对象中过滤出符合条件的元素,返回一个 迭代器,其中包含所有符合条件的元素。

语法

filter(function, iterable)
  • function:一个函数,它接受可迭代对象的元素,并返回 TrueFalseTrue 表示保留该元素,False 表示过滤掉该元素。

  • iterable:一个可迭代对象,如列表、元组等。

示例:过滤掉列表中的偶数

lst = [1, 2, 3, 4, 5] 
result = filter(lambda x: x % 2 != 0, lst) 
print(list(result)) # 输出: [1, 3, 5]
  • filter() 的特点:它根据条件过滤元素,并返回一个新的迭代器,仅包含符合条件的元素。

3. reduce()将多个元素累积为一个值

reduce() 用于将一个二元函数应用于可迭代对象的元素,将多个元素“缩减”(累积)成一个单一的值。它返回的是最终的结果,而不是一个集合。

语法

from functools import reduce 
reduce(function, iterable, [initializer])
  • function:一个二元函数,它接受两个参数,返回一个新的结果。

  • iterable:一个可迭代对象,如列表、元组等。

  • initializer(可选):一个初始值,将作为 function 的第一个参数,默认为 None

示例:计算列表中所有数字的和

from functools import reduce 
lst = [1, 2, 3, 4, 5] 
result = reduce(lambda x, y: x + y, lst) 
print(result) # 输出: 15
  • reduce() 的特点:它将可迭代对象的所有元素依次应用于二元函数,最终返回一个值。它并不返回一个集合,而是返回一个“缩减”的结果。

  • 三者的对比:

    功能map()filter()reduce()
    目的将函数应用于每个元素,返回新的元素集合根据条件过滤出符合要求的元素将多个元素累积成一个单一的值
    输入一个函数和一个可迭代对象一个函数和一个可迭代对象一个二元函数和一个可迭代对象
    返回一个可迭代对象,包含每个元素经过函数处理后的结果一个可迭代对象,包含符合条件的元素一个单一的值,表示对所有元素的累积结果
    典型用法对每个元素进行某种转换筛选符合条件的元素执行某种累积操作,如求和、求积、求最大值等
    使用例子[1, 2, 3] -> [2, 4, 6](每个元素乘以 2)[1, 2, 3, 4] -> [1, 3](只保留奇数)[1, 2, 3, 4] -> 10(所有元素求和)

4、装饰器

4.1装饰器含义


在python中,装饰器本质是一个特殊的嵌套函数,它接收一个函数【被装饰的函数】做参数,并返回一个新的函数【装饰后的函数】

装饰器的最大作用:在不改变原有函数【被装饰的函数】的基础上给它添加新的功能。

4.2 装饰器的基本用法 

# 装饰器
def out_fun(function):
    def in_fun():
        print("挂上一颗星星")
        function()
        print("挂上一个礼物盒")
    return in_fun
 
# 被装饰函数
def my_tree():
    print("简简单单一棵树")
 
# 第一种调用方式
out_fun(my_tree)()
# 问:第一种调用方式,被装饰函数真的装饰了吗
my_tree()       # 并没有新增功能
 
# 第二种调用方式
my_tree = out_fun(my_tree)
# 问:第二种调用方式,被装饰函数真的装饰了吗
my_tree()


4.3 装饰器语法糖 


语法糖是由编程语言提供的,可以让代码更加简洁、高效、易读和易写。语法糖不改变不会带来新的功能,也不会改变编程的结果,但是使用它会更加方便。

python中有很多语法糖,已用的有:

(1)列表推导式

(2)集合推导式

(3)字典推导式

(4)f-string print(f"{}")

(5)解包

(6)装饰器

语法格式:

@装饰器函数名

def 被装饰函数名:

代码块

其实就是在被装饰函数的上面加一句话——@装饰器

# 装饰器
def out_fun(function):
    def in_fun():
        print("挂上一颗星星")
        function()
        print("挂上一个礼物盒")
    return in_fun
 
# 被装饰函数
@out_fun
def my_tree():
    print("简简单单一棵树")
 
my_tree()


4.4 被装饰函数有参数 


        若被装饰函数有参数,那么装饰器的内部函数也需要有参数,保证在内部调用被装饰函数的时候能正确传参。

4.4.1 被装饰函数有一个参数

def out_fun(function):
    def in_fun(x):
        print("挂上一颗星星")
        function(x)
        print("挂上一个礼物盒")
    return in_fun
 
# 被装饰函数
@out_fun
def my_tree(x):
    print(f"简简单单{x}棵树")
 
my_tree(3)


4.4.2 被装饰函数有未知个参数 
 

import time
# 装饰器
def out_fun(function):
    def in_fun(*args, **kwargs):
        start = time.time()
        function(*args, **kwargs)
        end = time.time()
        print(end - start)
    return in_fun
 
# 被装饰函数1
@out_fun
def fun1(x):
    time.sleep(1)
    print(x)
fun1(1)
# 被装饰函数2
@out_fun
def fun2(x, y, z):
    time.sleep(1)
    print(x + y + z)
fun2(1,2,3)


4.5 装饰器带参数


        上面3.4是被装饰函数带有参数,我们在装饰器内部函数设置参数,以保证参数的正确传递。

        现在装饰器要带有参数,而且装饰器的外部函数要接收被装饰函数的函数名,内部函数要接收被装饰函数的参数,那么为了保证装饰器参数、被装饰函数参数的正确传递,我们在装饰器外部函数再嵌套一层函数,用于接收装饰器参数。

# 装饰器
def decoration(dec_arg):
    def out_fun(function):
        def in_fun(x):
            print(dec_arg)
            print("挂上一颗星星")
            function(x)
            print("挂上一个礼物盒")
        return in_fun
    return out_fun
 
# 被装饰函数
@decoration("我是装饰器的参数")
def my_tree(x):
    print(f"简简单单{x}棵树")
 
my_tree(3)


4.6 装饰器嵌套


已学的嵌套:列表、字符串、元组、集合、字典、函数、循环、选择

装饰器嵌套就是被装饰函数 可以 被多个装饰器装饰。

# 装饰器1
def out_fun_1(function):
    def in_fun_1(*args, **kwargs):
        print("装饰器1开始调用")
        function(*args, **kwargs)
        print("装饰1结束调用")
    return in_fun_1
 
# 装饰器2
def out_fun_2(function):
    def in_fun_2(*args, **kwargs):
        print("装饰器2开始调用")
        function(*args, **kwargs)
        print("装饰2结束调用")
    return in_fun_2
 
# 嵌套装饰 被装饰函数
@out_fun_1
@out_fun_2
def my_tree(x):
    print(f"{x}棵树")
 
my_tree(3)


4.7 类装饰器


        除了可以自定义一个新的函数用作装饰器之外,也可以将一个类作为装饰器,为被装饰的函数添加新的功能。类装饰器通过实现类的__call__方法,使得类的实例可以被当作函数来调用,丛而实现对其他函数的装饰。


原文地址:https://blog.csdn.net/m0_67609958/article/details/143722781

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!