Python | 万字详解闭包与装饰器(面试常考点)

本文深入探讨Python中的闭包和装饰器,包括它们的概念、使用方法、优势以及在面试中的常见应用场景。详细讲解了如何编写计时装饰器、实现权限控制,并通过logging模块展示了装饰器在日志管理中的应用。此外,还介绍了property内置装饰器和基于类实现装饰器的方法,帮助读者更好地理解和掌握装饰器的运用。
摘要由CSDN通过智能技术生成

 创作不易,来了的客官点点关注,收藏,订阅一键三连❤😜 

前言

“人生苦短,我用python”,我是一个即将毕业的大学生,超超。如果你也爱python,不妨跟着萌新超超一起学习python,拿下python,一起加油,共同努力,拿到理想offer!


系列文章目录

python | 面向对象(四):python的自省、元类、抽象基类

Python | python中的下划线,常用魔术方法与属性

Python | 经典类与新式类,静态方法、类方法与实例方法详解!


概述

本期内容是python中的闭包和装饰器知识,面试中常考知识点,万字详解,拿下它!


目录

前言

系列文章目录

概述

闭包

什么是闭包

生命周期

满足闭包的条件

闭包的使用

闭包的好处

装饰器

什么是装饰器

装饰器的用途

编写一个计时的装饰器

用装饰器实现权限控制

两个装饰器作用于函数

保留元顺序

装饰器带参数

装饰器装饰类

装饰器的应用:使用logging模块

了解日志

日志的五个级别

logging模块的使用

内置装饰器:property

基于类实现装饰器

用类创建装饰器并传入参数

装饰器总结

为什么使用装饰器

在何处使用装饰器

三句话总结装饰器

面经拓展

du与df的区别

重新加载和重新启动的区别


闭包

什么是闭包

• 在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。

• 闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。

• 在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。

闭包的概念很简单:一个可以引用在函数闭合范围内变量的函数。即"内部函数",只有那个内部函

数才有所谓的__closure__属性。

生命周期

# a=1 定义时开始,执行完结束。生命周期定义了程序的开始与结束

def func1():

    a = 10

    print(f" test {a}")

 

func1()    

# 注:函数调用完 a就释放了,生命周期是函数调用的时间

# print(a) 

# 注:打印不出来

#变量解析原则: LEGB原则:local enclosing global build-in



def outer(x):

    a = 300

    def inner():

        print(x + a)

    return inner # 返回inner函数

d = outer(10) # 此时d是inner函数

d() # d()返回inner()的结果:310

print(dir(d))

print(d.__closure__) # closure里保存了两个整数

满足闭包的条件

1.必须有一个内嵌函数

2.内函数必须引用外函数的变量

3.外函数必须返回内函数

闭包的使用

• 形成闭包之后,闭包函数会获得一个非空的__closure__属性(对比我们最后的函数test,test是一个不具备闭包的函数,它的__closure__属性是None),这个属性是一个元组

• 元组里面的对象为cell对象,而访问cell对象的cell_contents属性则可以得到闭包变量的当前值(即上一次调用之后的值)。

• 而随着闭包的继续调用,变量会再次更新。

• 所以可见,一旦形成闭包之后,python确实会将__closure__和闭包函数绑定作为储存闭包变量的场所

def outer():

    tmp_list = []

    def inner(name):

        tmp_list.append(1)

        print("%s -- %s"%(name,tmp_list))

    return inner

 

d1 = outer()

d1("d1")

# 输出结果

# d1 -- [1]

d1("d1")

# 输出结果

# d1 -- [1, 1]

d2 = outer()  # 每次调用函数都会重新执行

d2("d2")

# 输出结果

# d2 -- [1]

每次调用外函数,都会重新执行,创建一个新的tmp_list和inner,代码虽然一样,但是创建不同对象

def outer():

    fs = []

    for i in range(5):

        def inner():

            return i*i

        fs.append(inner)

    return fs

f1,f2,f3,f4,f5 = outer()  # 执行完outer后,i的值为4了

print(f1())

# 输出结果:16

print(f2())

# 输出结果:16

print(f3())

# 输出结果:16

print(f4())

# 输出结果:16

print(f5())

# 输出结果:16

闭包的好处

• 闭包不是必须的。

• 没了闭包,python的功能一点不会被影响

• 有了闭包,只是提供给你一种额外的解决方案。

装饰器

什么是装饰器

装饰器的本质是闭包在不改变函数或类的源代码基础上,添加额外功能

• 装饰器的本质是闭包,它需要一个callable对象(函数,类)作为参数传入

• 装饰器是这样一种设计模式:如果一个类(函数)希望添加其他类(函数)的一些功能,

不希望通过继承或是直接修改源代码实现,那么可以使用装饰器模式。(不改变源代码的情况下增加新的功能

• 简单来说Python中的装饰器就是指某些函数或其他可调用对象,以函数或类作为可选输入参数,然后返回函数或类的形式。通过这个在Python2.6版本中被新加入的特性可以用来实现装饰器设计模式。

• 装饰器就是一个可以接受调用也可以返回调用的函数,该函数接受被装饰的函数作为其位置参数。装饰器通过使用该参数来执行某些操作,然后返回原始参数或一些其他的调用

• 函数也是对象,也可以当做参数传递

装饰器的用途

我们可以考虑在装饰器中置入通用功能的代码来降低程序复杂度

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chaochao️

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值