首页 > 编程语言 >17.Python基础篇-闭包、装饰器、迭代器、生成器

17.Python基础篇-闭包、装饰器、迭代器、生成器

时间:2024-10-17 17:22:20浏览次数:1  
标签:闭包 函数 17 生成器 inner func print 装饰 def

函数的进阶—闭包

闭包的定义:嵌套函数,内部函数调用外部函数的变量。满足这个条件就算闭包。

闭包案例演示:

def outer():
    a = 1
    def inner():
        print('inner函数中打印的变量a:',a)  # 嵌套函数中使用了外层函数的变量。此时满足了闭包的条件。
    return inner  # 常用的方式,将inner的内存地址作为返回值,可以在外部直接调用inner,并且inner可以使用外层的变量:a。从而延长了变量a的生命周期

inn = outer()
print('打印inn', inn)  # 打印结果为inner函数的内存地址
inn()  # 内存地址+(),即表示调用inner这个函数

输出内容:
打印inn <function outer.<locals>.inner at 0x0000028217752670>
inner函数中打印的变量a: 1

 

 函数的进阶-装饰器

装饰器的作用

主要作用是在不修改原始函数的情况下,为其增加额外的功能。应用于日志功能:记录函数的调用;性能测试:统计函数执行的时间等...

完整的装饰器固定写法

1.0版本-不使用语法糖的写法(为了便于理解)

# 装饰器的固定写法(不使用语法糖得版本,为了便于理解)

# 定义一个装饰器函数
def wrapper(func):  # 接收被装饰函数的函数名(内存地址)
    def inner(*args, **kwargs):  # 这俩可变参数可以兼容所有参数类型的函数
        print("在被装饰函数之前要做的事情")
        ret = func(*args, **kwargs)  # 调用被装饰函数,并接收返回值
        print("在被装饰函数之后要做的事情")
        return ret  # 将被装饰函数的返回值,返回给调用者
    return inner

# 被装饰的函数
def func(a, b):
    print("被装饰的函数")
    print("打印两个参数:", a, b)


func = wrapper(func)
func(1, 2)  # 调用func演示

2.0版本-使用语法糖的写法

# 装饰器的固定写法(使用语法糖)

# 定义一个装饰器函数
def wrapper(func):  # 接收被装饰函数的函数名(内存地址)
    def inner(*args, **kwargs):  # 这俩可变参数可以兼容所有参数类型的函数
        print("在被装饰函数之前要做的事情")
        ret = func(*args, **kwargs)  # 调用被装饰函数,并接收返回值
        print("在被装饰函数之后要做的事情")
        return ret  # 将被装饰函数的返回值,返回给调用者
    return inner

# 被装饰的函数
@wrapper  # @wrapper 等价于 func = wrapper(func) 。使用@wrapper语法糖把函数加上装饰器
def func(a, b):
    print("被装饰的函数")
    print("打印两个参数:", a, b)


func(1, 2)  # 调用func演示

语法糖是什么:本质上,语法糖是对已有语法结构的封装或简化,让开发者用更简洁的方式表达复杂的逻辑。(引用于ChatGPT)

在python中有些功能使用了语法糖特性?

  1. Lambda 表达式
  2. 装饰器
  3. 三元表达式
  4. 解包赋值

3.0版本-使用@wraps装饰器,解决被装饰函数无法获取真实的函数名问题

背景:使用函数名.__name__可以获取函数的函数名。但是如果按照前面的写法,将无法获取被装饰函数的真实函数名,实际拿到的是装饰器函数的方法名。代码说明:

def func1_name():
    pass

print(func1_name.__name__)  # 打印出func1_name函数的函数名

输出结果:
func1_name

 

 

# 定义一个装饰器函数
def wrapper(func):
    def inner(*args, **kwargs):
        print("在被装饰函数之前要做的事情")
        ret = func(*args, **kwargs)
        print("在被装饰函数之后要做的事情")
        return ret
    return inner

# 被装饰的函数
@wrapper
def func(a, b):
    print("被装饰的函数")
    print("打印两个参数:", a, b)

print(func.__name__)

输出结果:
inner

# func是被装饰的函数,按理说我们的需求打印出的应该是"func",也就是函数本身的方法名。现在的执行结果却是"inner"(装饰器内部嵌套函数的方法名)。
# 为了解决获取不到被装饰函数的真实函数名问题,则需要使用functools中的@wraps装饰器,装饰在装饰器的内部方法上
from functools import wraps

def wrapper(func):
    @wraps(func)   # 装饰器内部函数增加@wraps方法装饰后,就支持查看被装饰函数真实的函数名
    def inner(*args, **kwargs):
        print("在被装饰函数之前要做的事情")
        ret = func(*args, **kwargs)
        print("在被装饰函数之后要做的事情")
        return ret
    return inner

# 被装饰的函数
@wrapper
def func():
    print("被装饰的函数")


print(func.__name__)  # 打印被装饰函数的函数名

输出结果:
func

 

4.0版本-三层嵌套的装饰器,支持装饰器传参,可以用传入标志位来控制装饰器是否生效

 

标签:闭包,函数,17,生成器,inner,func,print,装饰,def
From: https://www.cnblogs.com/mingbo-1/p/18472729

相关文章

  • PostgreSQL 17重磅登场——世界上最成功的数据库
    朋友们,万众期待的PostgreSQL大版本发布又来了!这一次,PostgreSQL17带着全新的性能优化和开发者必备的新功能强势登场。与其说这是一场普通的更新,不如说它是一场专为高并发工作负载和海量数据量身打造的技术嘉年华! 在本次的发布说明中,PostgreSQL全球社区也毫不讳言地直接宣布......
  • 2024/10/17 模拟赛总结
    \(100+50+0+35=185\),呃呃呃,终于吃上LRX了#A.语言考虑名词性词组的性质,由于它可以由任意名词,形容词和名词性词组拼接起来,那么连续的名词,形容词或交替出现都是可行的但是如果最后一个是形容词不可行,不然它就无法修饰其他词语了于是可以枚举那一个单独的动词,判断前面和后面知......
  • 2024/10/17日 日志 --》关于MySQL中的 约束、多表查询的初步学习笔记与整理
    今天推进了关于约束以及多表查询的内容,下一步是事务以及关于连接数据库JDBC的学习。点击查看代码----约束--1.概念:--·约束是作用于列上的规则用于限制加入表的数据--·约束的存在保证了数据库中数据的正确性、有效性和完整性--2.约束的分类--非空约束NOTNULL:......
  • 【进阶OpenCV】 (17)-- Dlib库 --实现人脸检测
    文章目录Dlib库一、Dlib库安装二、实现人脸检测1.生成人脸检测器2.检测人脸3.显示人脸总结Dlib库Dlib提供了丰富的图像处理和计算机视觉工具,如面部特征检测、物体检测、图像变换等,这些工具使得开发者能够轻松地进行各种图像处理任务。一、Dlib库安装pipinst......
  • 2024.10.17总结
    本文于github博客同步更新。远古题,放现在强度不高。A:处理出每日融化积雪的前缀和,设第\(i\)天,则向二分查找的数组中添加\(sum[i-1]+a[i]\),之后查找第\(j\)天的\(sum[j]>=sum[i-1]+a[i]\),进行差分,\(ans[j]+=sum[i-1]+a[i]-sum[j-1]\),来处理不完全部分,最后,\(ans[i]+=nu......
  • 2024-10-17_Thu_14:19 - 你的意念强度决定你的富裕程度
    2024-10-17_Thu_14:19-你的意念强度决定你的富裕程度​​‍你到底想要什么?有钱人努力让自己有钱。穷人一直想要变得有钱。如果问大部分人想不想变成有钱人,他们会看着你,把你当作疯子,然后说:“我当然想有钱啊。”然而事实上大部分的人并不是真的想变得有钱。为什么?因为......
  • 24.10.17
    签到,爽!为啥我把这个放考试三个题上面?A签到!每天所有数\(\let_i\)的取完,剩下的减\(t_i\),没有脑子只剩平衡树了。B签到!必须01交错?将\(2|(i+j)\)的格子取反就是求最大全零矩阵和最大全一矩阵。悬线法。0:6C签到?\(m\le10\),状压,但是\(2\times3\)的物品需要压两......
  • 2024-10-17_Thu_13:52 - 财富目标:求其上者得其中
    2024-10-17_Thu_13:52-财富目标:求其上者得其中​​态势:攻与守有钱人玩金钱游戏是为了赢。穷人玩金钱游戏是为了不要疏。意念的力量很惊人!‍目标:求其上者得其中,求其中者得其下,求其下者无所得致富法则如果你的目标是过得舒服就好,你就很可能永远也不会有钱。但是如......
  • 2024-10-17_Thu_13:52 - 财富目标:求其上者得其中
    2024-10-17_Thu_13:52-财富目标:求其上者得其中​​态势:攻与守有钱人玩金钱游戏是为了赢。穷人玩金钱游戏是为了不要疏。意念的力量很惊人!‍目标:求其上者得其中,求其中者得其下,求其下者无所得致富法则如果你的目标是过得舒服就好,你就很可能永远也不会有钱。但是如......
  • GitLab 发布安全补丁版本 17.3.2, 17.2.5, 17.1.7
    本分分享极狐GitLab补丁版本17.4.2,17.3.5,17.2.9的详细内容。这几个版本包含重要的缺陷和安全修复代码,我们强烈建议所有私有化部署用户应该立即升级到上述的某一个版本。对于极狐GitLabSaaS,技术团队已经进行了升级,无需用户采取任何措施。极狐GitLab正式推出面向GitLab......