Python高阶函数以及装饰器

1、闭包函数

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

形成闭包的条件:

1.函数嵌套

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

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

python 复制代码
def out_fun(x):
    def in_fun(y):
        return y**x
    return in_fun
print(out_fun(2)(3))

2、lambda匿名函数

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

代码示例:

python 复制代码
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() 用于将一个指定的函数应用到可迭代对象的每个元素上,返回一个 迭代器,其元素是原始可迭代对象的每个元素经过函数处理后的结果。

语法

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

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

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

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

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

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

语法

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

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

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

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

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

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

语法

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

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

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

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

python 复制代码
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 装饰器的基本用法

python 复制代码
# 装饰器
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 被装饰函数名:

代码块

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

python 复制代码
# 装饰器
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 被装饰函数有一个参数

python 复制代码
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 被装饰函数有未知个参数

python 复制代码
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是被装饰函数带有参数,我们在装饰器内部函数设置参数,以保证参数的正确传递。

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

python 复制代码
# 装饰器
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 装饰器嵌套

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

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

python 复制代码
# 装饰器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__方法,使得类的实例可以被当作函数来调用,丛而实现对其他函数的装饰。

相关推荐
QTX1873011 分钟前
前端基础的讲解-JS(10)
开发语言·前端·javascript
forth touch15 分钟前
c++ shared_ptr 常见构造函数
开发语言·c++
网络安全-海哥18 分钟前
【VLANPWN】一款针对VLAN的安全研究和渗透测试工具
开发语言·javascript·安全·ecmascript·php·网安入门
Beekeeper&&P...23 分钟前
瑞吉外卖中r类的作用
开发语言·spring
zanglengyu28 分钟前
RK3568硬解码并与Qt界面融合显示深入探究
开发语言·qt·ffmpeg·rk3568硬解码rtsp
AI原吾35 分钟前
探索Python的HTTP利器:Requests库的神秘面纱
python·requests
西域编娃36 分钟前
探索Scala编程:图书管理系统实战
开发语言·scala
刘翔在线犯法39 分钟前
Scala例题
开发语言·后端·scala
anqi2739 分钟前
Scala 的List
开发语言·后端·scala
Word的妈呀40 分钟前
Scala的case class
开发语言·后端·scala