Python的装饰器

这篇具有很好参考价值的文章主要介绍了Python的装饰器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:
    🤡 作者简介:我是Morning,计算机的打工人,想要翻身做主人 🙈 🙈 🙈
    🏠 个人主页:Morning的主页
    📕系列专栏::Morning的Python专栏
    📞 如果小编的内容有欠缺或者有改进,请指正拙著。期待与大家的交流
    🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏

目录

一.闭包

1.闭包的必要性

2.定义

3.调用和引用的区别

二.装饰器

1.定义:

2.意义

3.实现方式

4.使用案例

(1)原来思维

(2)使用闭包实现装饰器

三.语法糖

1.简介

2.使用案例

(1)简单的直接使用

(2)有传参

(3)使用函数嵌套进行语法糖传参

3.类与装饰器的使用

(1)装饰类方法

(2)装饰类


一.闭包

在今后的学习中装饰器会起到很大的作用,而装饰器就是基于闭包来实现的

1.闭包的必要性

在一个函数中如果想要想要使用一个变量,我们最直接的方法就是设置一个全局变量。但是这个变量如果只会使用一两次,那么直到代码进行结束前,那个全局变量一直都会占用着资源,不会被销毁,会浪费资源。

2.定义

一个函数中若要用到另一个函数的参数,则可以通过闭包的形式来实行

顾名思义,闭包(封闭包含),在下面这段函数中便能体现出来

def A():
    a=1
    def B():
        b=2
        print(a)

对于函数闭包而言,某一个函数中用到的变量的作用域,取决于其上层或者本层函数函数的作用域。

对于嵌套函数而言,内层函数中定义的变量是无法在外层函数进行使用的(即在B函数中可以调用a,但是不能在A函数中调用b)

此外可以直接调用函数A(),但是不能调用函数B()

3.调用和引用的区别

调用:会直接从内存中去取出相应的对象执行,代码会直接执行

引用:设置了一个路标,该路标指向某一个内存地址中的对象。此时相当于加载了代码在一个缓存空间内,代码并没有被执行。

提醒:如果在没有返回值return的情况下调用闭包函数时,只会调用外层函数,不会调用内层函数

def Student():
    name="susu"
    age=21
    print(f"{name}{age}了")
    def School():
        adress="河北"
        banji=204
        print(name+"在"+adress+"上学")
    return School
s=Student()
print(s)   #结果见图一
def Student():
    name="susu"
    age=21
    print(f"{name}{age}了")
    def School():
        adress="河北"
        banji=204
        print(name+"在"+adress+"上学")
    return School
Student()
School()  #结果见图二
def Student():
    name="susu"
    age=21
    print(f"{name}{age}了")
    def School():
        adress="河北"
        banji=204
        print(name+"在"+adress+"上学")
    return School
Student()() #结果见图三
​
def Student():
    name="susu"
    age=21
    print(f"{name}{age}了")
    def School():
        adress="河北"
        banji=204
        print(name+"在"+adress+"上学")
    return School()
Student()  #结果见图四
​

图一

python 装饰器,Python,python

图二

python 装饰器,Python,python

图三

python 装饰器,Python,python

图四:

python 装饰器,Python,python

在上面的例子中,School便是引用,School()则是调用。在return School的情况下调用Student函数会发现运行结果中出现的是School函数(即图一);如果调用Student函数的基础上再加个()那么School函数也会被调用(即图三)。

二.装饰器

1.定义:

能够在不改变原有函数的基础上,在原来的基础上添加额外的功能的代码,就叫做装饰器

2.意义

登陆注册(验证账号、密码的准确性)、爬虫中(某一个请求需要在异常之后补充请求头参数然后再去重新对当前请求进行发送)

3.实现方式

对于装饰器的定义,基于函数闭包的形式来实现,即可以将某一个函数作为参数传递给另一个函数,在这另一个函数中去为函数添加功能。

4.使用案例

(1)原来思维

def index():
    print("这里有着大家要的学习资料")
    print("suyuxi")
#对于index而言,它的功能是已经实现了的,不希望重构代码
#(编程都流传着一句话,只要你的程序跑起来,哪怕你知道它有bug那也不要去改哈哈哈)所以登陆的权限就交给了其他的函数来实现
def login(func,username,password):
    if username=="sumaolin" and password=="aisuyuxi":
        func()#传递实参来调用函数
    else:
        print("你无权限,请与管理员联系")
        return 0
login(index,"sumaolin","aisuyuxi")

但是这样的代码可读性并不高。一个函数就添加了三个参数,阅读起来就需要一点一点地去理解,不用说肯定很烦。

(2)使用闭包实现装饰器

那我们有没有一种方法来直接调用index函数呢?那我们就要使用闭包函数来实现装饰器

def index():
    print("这里有着大家要的学习资料")
    print("suyuxi")
#下面便是一个自定义的装饰器。用inner函数来进行修饰func,如果满足条件后再来调用func。从而实现为func添加功能
def login(func):
    username="sumaolin"
    password="aisuyuxi"
    def inner():
        if username == "sumaolin" and password == "aisuyuxi":
            return func()
        else:
            print("你无权限,请与管理员联系")
            return 0
    return inner
login(index)()

此处可能会有人问,为什么不直接返回inner(),而是返回inner。其实两个都能达到我们的目的,只是在此例中我更想突出的是:inner是为了给func添加功能,因此返回的是func函数,然后在对其进行调用

但是说到底我们还是阅读起来不直观,还是需要一步一步地去理解。我们想要一个阅读性更强的代码,那么语法糖就可以解决这个问题

三.语法糖

1.简介

python中去执行修饰器的一种语法规则

写法:@decorator 语法糖都要写在某一个函数定义的头上,表示decorator函数修饰下面的函数

那为什么要去使用它呢。简单理解的话,就是如果你要去修饰一栋墙,你肯定不会是去把墙拆了重新修,而是在之前的基础上进行修饰。代码也是如此,原先的代码我们能不动的话就不动,然后写修饰代码来对原代码进行修饰。

2.使用案例

(1)简单的直接使用

def login(func):   #接收被修饰的对象(对象可以是函数、类、类中的方法)
    username="sumaolin"
    password="aisuyuxi"
    def inner():
        if username == "sumaolin" and password == "aisuyuxi":
            return func()
        else:
            print("你无权限,请与管理员联系")
            return 0
    return inner
#语法糖出现在函数上方,此处表示index函数被装饰器login装饰,login叫做装饰器(n.也叫装饰函数)
#login修饰index的过程是叫装饰函数(v.)
@login
def index():
    print("这里有着大家要的学习资料")
    print("suyuxi")
index()

大家可以看出来除了语法糖的使用外只有调用不同,曾经我都怀疑过是否生效了。

大家仔细看我的注释的话是可以理解的,在外层接受了被装饰的对象index(也可以理解为func是被装饰的对象,即index。所以func就是index)

这样已经可以实现一个比较简单的语法糖了。

(2)有传参

def login(func):   #最外层接收被修饰的对象(对象可以是函数、类、类中的方法)
    username="sumaolin"
    password="aisuyuxi"
    def inner(level):#2
        if username == "sumaolin" and password == "aisuyuxi":
            return func(level)#3
        else:
            print("你无权限,请与管理员联系")
            return 0
    return inner
#语法糖出现在函数上方,此处表示index函数被装饰器login装饰,login叫做装饰器(n.也叫装饰函数)
#login修饰index的过程是叫装饰函数(v.)
@login
def index(level):#4
    print("这里有着大家要的学习资料")
    print("suyuxi")
index(1)#1

在注释中我标注了四个数字。如果我们想要在4处,即我们想要实现的主要代码添加一个形参。那么我们就需要在1处添加实参。但是在调用时3处func的调用肯定也是需要一个形参的,此时的inner又必须与func保持一致,所以2处也必须添加形参。

总的来说,添加一个实参,就需要添加三个形参,说到底我们还是将问题复杂了。

(3)使用函数嵌套进行语法糖传参

但是在进行传参时我们需要注意是不能在装饰器函数设置形参的。最好的方法就是再进行函数的嵌套

def sugar(level):
    def login(func):
        username="sumaolin"
        password="aisuyuxi"
        def inner():
            if username == "sumaolin" and password == "aisuyuxi":
                print(f"您的会员等级为{level}")
                return func()
            else:
                print("你无权限,请与管理员联系")
                return 0
        return inner
    return login
@sugar(3)
def index():
    print("这里有着大家要的学习资料")
    print("suyuxi")
index()

3.类与装饰器的使用

(1)装饰类方法

def decorator(func):
       #print(func)
       def inner():#1
           return func()#2
       return inner
​
class A:
    @decorator
    def hobby(self):
        print("打苏钰烯")
a=A()
a.hobby()

按照我们以前的思想,应该是这么写,但是运行后报错。为了便于理解我们打印一下func到底是什么

python 装饰器,Python,python

我们可以看出是类A的实例方法hobby,那么在1和2处我们就需要接受一个self

def decorator(func):
       print(func)
       def inner(self):#1
           return func(self)#2
       return inner
​
class A:
    @decorator
    def hobby(self):
        print("打苏钰烯")
a=A()
a.hobby()

(2)装饰类

def decorator(func):
    def inner():
        return func()
    return inner
@decorator  #该装饰器装饰的是整个类,而不是一个单独的方法,在对类实例化的时候就会调用装饰器
class A:
    def hobby(self):
        print("kkk")
    def love(self):
        print("girl")
a=A()
a.hobby()
a.love()

修饰类的话,那么类中的方法对会被修饰

以上便是我对装饰器的理解,感觉还是不到位,讲解的也十分抽象,因为在实际中的使用还很少。但是会加油的,期待与大家的交流。

还有一位博主的语法糖讲解的比我说的更加条例高效,大家可以看一看(5条消息) Python语法糖装饰器---由浅入深(看一遍就懂系列)_Felix-微信(Felixzfb)的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-530198.html

到了这里,关于Python的装饰器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python闭包与装饰

    闭包与装饰的本质 一个函数的组成部分可以包含: 变量 函数 类 闭包和装饰的本质: 组成部分中的函数引用了组成部分中的其他变量、函数、参数,return该组成部分函数。 闭包 定义:利用nonlocal声明函数组成部分中的变量,返回组成部分中的函数。 实际使用:定义一个函

    2024年01月17日
    浏览(33)
  • Python的装饰器

    前言:     🤡 作者简介:我是Morning,计算机的打工人,想要翻身做主人 🙈 🙈 🙈     🏠 个人主页:Morning的主页     📕系列专栏::Morning的Python专栏     📞 如果小编的内容有欠缺或者有改进,请指正拙著。期待与大家的交流     🔥如果感觉博主的文章还不错的话,

    2024年02月12日
    浏览(17)
  • Python初步了解装饰器

    装饰器的概念 装饰器的简单使用 装饰器的进阶 装饰器的练习 装饰器的固定模块 装饰器的语法糖

    2024年02月09日
    浏览(28)
  • Python装饰器

    是一种高级功能,用于在不修改函数源代码的情况下,向函数添加额外的功能。它允许我们修改或增强函数的行为,类似于“装饰”或“修饰”原始函数。装饰器本质上是一个高阶函数,它接受一个函数作为输入,并返回一个新的函数作为输出。 使用装饰器的主要优势之一是

    2024年01月17日
    浏览(63)
  • 【Python】闭包 | 装饰器

    在函数嵌套的前提下,内部函数使用到了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包。 需要使用 nonlocal 修饰外部函数的变量才可在内部函数中修改它。 闭包注意事项 优点 无需定义全局变量即可实现通过函数,

    2024年02月09日
    浏览(27)
  • python装饰器嵌套基础

    python支持装饰器嵌套,即多个装饰器装饰同一个函数或方法。 用法 描述 @a_deco、@b_deco、@c_deco分别占一行,编写在同一个函数或方法的def语句上方。 从def开始,由近到远,依次执行装饰器@c_deco、@b_deco、@c_deco。 等价于 示例 描述 装饰器的包装函数,比如a_wrapper(),保存接收到

    2024年01月25日
    浏览(28)
  • python 装饰器

    应用场景

    2024年02月17日
    浏览(25)
  • python的装饰器详解

    目录 一:介绍 二:在方法中使用 三:在类中使用 四:python自带的装饰器 一:介绍 Python的装饰器是一种高阶函数,它允许你在不改变函数内部逻辑的情况下,给函数添加额外的功能。装饰器本质上是一个接受函数对象作为参数,返回一个新的函数对象的可调用对象(通常是

    2024年01月16日
    浏览(26)
  • Python中的装饰器详解及实际应用【第120篇—装饰器详解】

    在Python编程中,装饰器(Decorator)是一种强大而灵活的工具,用于修改函数或方法的行为。它们广泛应用于许多Python框架和库,如Flask、Django等。本文将深入探讨装饰器的概念、使用方法,并提供实际应用的代码示例和详细解析。 装饰器是一种特殊的函数,它可以接受一个函

    2024年03月11日
    浏览(42)
  • Python教程(24)——全方位解析Python中的装饰器

    Python装饰器是一种特殊的函数,它接收一个函数作为参数,然后返回一个新的函数,用于扩展或修改原始函数的行为。装饰器提供了一种便捷的方式来在不修改被装饰函数源代码的情况下,增加、修改或包装函数的功能。通俗点说就是尽量不修改原有功能代码的情况下,给原

    2024年02月02日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包