返回顶部
首页 > 资讯 > 后端开发 > Python >python装饰器进阶
  • 280
分享到

python装饰器进阶

进阶python 2023-01-30 23:01:42 280人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录 装饰器进阶 1. 被装饰的函数有多个参数。 2. 被装饰的函数有返回值 3.在函数中嵌入装饰器 4. 装饰器类

目录

  • 装饰器进阶
    • 1. 被装饰的函数有多个参数。
    • 2. 被装饰的函数有返回值
    • 3.在函数中嵌入装饰器
    • 4. 装饰器类
    • 总结

通过上一篇已经知道, 如果还有不理解什么是装饰器,请返回 装饰器入门。 前面一篇算是装饰器的入门 。装饰器在 python语言中有着非常重要的应用。小到脚本的开发,大到很多功能负责的WEB框架开发。正如我们所知, 前面所看到的被装饰的 函数都是最简单函数格式, 这里所说的简单, 是指 函数无参数的形式,或者函数没有返回(直接执行结果)值。 在实际开发中 被装饰的函数并非我们见到如此简单的格式,更多的复杂的函数如多返回值多参数(形式参数,关键字参数, 所以这一篇算是Python装饰器的一个进阶。

1. 被装饰的函数有多个参数。

场景一: 一个简单的认证装饰器

  • 实例代码

    from functools import wraps
    
    def auth2(func):
        @wraps(func)
        def wrapper(*arg, **kwargs):
            user = input("pls input passWord:").strip()
            if user == "faily":
                print("---welcome login----")
                func(*arg, **kwargs)
          else:
              print("----wrong password----")
      return wrapper
    
    @auth2
    def task2(name, is_happy="Yes"):
                    print("{0} is doing somthing, Is he happy? [{1}]".fORMat(name, is_happy))
    
    
    if __name__ =="__main__":
         '''带参数的装饰器'''
         task2("faily")

    可以看出,被装饰的函数task2 拥有两个参数,name, is_happy, 那么如何将两个参数传递进装饰器函数中呢?

  1. 根据前面我们所学的知识,可以看出, 装饰器在执行的时候, 首先将被装饰的 函数名 这里是task2传递给装饰器函数 auth2, 那么被装饰函数的参数 就不得不找别的地方传进去, 唯一可以接受这些变量的地方就是 wrapper函数.
  2. 通过wrapper 函数将参数传进去之后呢, 再建参数传递个 被装饰的函数 即可

2. 被装饰的函数有返回值

  • 显然 这种函数最普遍, 函数在执行后立即展示结果,而是作为值进行传递

    from functools import wraps
    
    def auth3(func):
    
        @wraps(func)
        def wrapper(arg):
            user = input("pls input password:").strip()
            if user == "faily":
                print("---welcome login----")
                return func(arg)
            else:
                print("----wrong password---")
    
        return wrapper
    
    @auth3
    def task3(name):
        print("do somthing ")
        return name
    
    if __name__ == "__main__":
        ts = task3("momo")
        print(ts)

    这种很好理解, 函数有返回值, 那么在wrapper函数内执行完新加功能后, 直使用关键字 return将被装饰的函数 返回

3.在函数中嵌入装饰器

在这里我们可以这样理解: 既然装饰器是高阶函数 + 嵌套函数 = 装饰器 那么可不可以有这种组合呢, 即 嵌套函数 + 装饰器函数的形式呢?

答案是肯定的

其实这种应用也可理解为: 之前我们写的所有装饰器函数自己都不带参数的,既然装饰器本质也是函数 ,那么装饰器函数是否可以带参数呢?? 格式是什么样子呢?
通过下面的例子进行说明

  • 回到日志的例子,并创建一个包裹函数,能让我们指定一个用于输出的日志文件

    from functools import wraps
    
    def logit(logfile='out.log'):
    
        # 装饰器 
        def logging_decorator(func):
            @wraps(func)
            def wrapped_function(*args, **kwargs):
                log_string = func.__name__ + " was called"
                print(log_string)
                # 打开logfile,并写入内容
                with open(logfile, 'a') as f:
                    # 现在将日志打到指定的logfile
                    f.write(log_string + '\n')
                return func(*args, **kwargs)
           return wrapped_function
        return logging_decorator
    
    #默认装饰器参数
    @logit()
    def myfunc1(action="run"):
        if action == "run":
            return True
        else:
            return False
    
    #装饰器传参
    @logit(logfile='func2.log')
    def myfunc2(action = "stop"):
        if action == "run":
            return True
        else:
            return False
    
    if __name__ == "__main__":
      myfunc1()
      myfunc2()
    
    # 现在一个叫做 func2.log 的文件出现了,里面的内容就是上面的字符串 

    这个例子中, 是不是觉得装饰器实在是太强大了?

  • 可以通过为装饰器给予不同的参数实现不同函数日志输出的新增功能, 我们只是在标准装饰器外加了一层函数, 这个函数实际就是为了用来将装饰器的参数传递进包裹函数中.

4. 装饰器类

场景分析 : 运维监控中, 我们常常需要记录不同级别,或者不同app产生的日志,但当我们的应用程序的某些部分还比较脆弱时,触发异常也许是需要更加关注的事情. 比方说有时只想记录日志到一个文件; 而有时你想在程序发生异常时送到一个email,同时也保留日志。这是一个使用继承的场景,但目前为止我们只看到过用来构建装饰器的函数。

幸运的是,类也可以用来构建装饰器。那我们现在以一个类而不是一个函数的方式,来重新构建logit

  • 装饰器类

    rom functools import wraps
    
    class logit(object):
        '''装饰器类'''
        def __init__(self, logfile='out.log'):
            self.logfile = logfile
    
        def __call__(self, func): # __call__说明这是一个callable
            @wraps(func)
            def wrapped_function(*args, **kwargs):
                log_string = func.__name__ + " was called"
                print(log_string)
                # 打开logfile并写入
                with open(self.logfile, 'a') as f:
                    # 现在将日志打到指定的文件
                    f.write(log_string + '\n')
                # 现在,发送一个通知
                self.notify()
                return func(*args, **kwargs)
            return wrapped_function
    
        def notify(self):
            # logit只打日志,不做别的
            pass

    这个实现有一个附加优势,在于比嵌套函数的方式更加整洁,而且包裹一个函数还是使用跟以前一样的语法:

    @logit()
    def myfunc1():
        pass

    现在,我们给logit创建子类,来添加email的功能。

    class email_logit(logit):
        '''
        一个logit的实现版本,可以在函数调用时发送email给管理员
        '''
        def __init__(self, email='admin@myproject.com', *args, **kwargs):
            self.email = email
            super(email_logit, self).__init__(*args, **kwargs) # 集成父类
    
        def notify(self):
            # 发送一封email到self.email
            # 这里就不做实现了
            pass

    从现在起,@email_logit将会和@logit产生同样的效果,但是在输出日志的基础上,还会多发送一封邮件给管理员。

总结

装饰器进阶已经讲完, 下一篇我们继续研究, 多重装饰器

--结束END--

本文标题: python装饰器进阶

本文链接: https://lsjlt.com/news/181275.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • python装饰器进阶
    目录 装饰器进阶 1. 被装饰的函数有多个参数。 2. 被装饰的函数有返回值 3.在函数中嵌入装饰器 4. 装饰器类 ...
    99+
    2023-01-30
    进阶 python
  • python装饰器3:进阶
    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 函数装饰器装饰方法 函数装饰器装饰普通函数已经很容易理解了: @decorator def func():... #等价于 def func():... func = dec...
    99+
    2023-01-30
    进阶 python
  • python进阶之装饰器
    一.无参装饰器 问题:如何计算一段程序的运行时间? 先看一段简单代码: 1 import time 2 def func(): 3 start = time.time() # 记录程序开始时间 4 time.sleep(...
    99+
    2023-01-30
    进阶 python
  • python 进阶学习之python装饰器小结
    装饰器总结 什么是装饰器?处理函数的函数,加一个功能,但是不影响原来函数的内部结构生活中的例子:给手机加一个外壳,外壳保护了手机 装饰器有什么用?增强函数的功能 装饰器使用场景增加被...
    99+
    2024-04-02
  • 老生常谈Python进阶之装饰器
    函数也是对象 要理解Python装饰器,首先要明白在Python中,函数也是一种对象,因此可以把定义函数时的函数名看作是函数对象的一个引用。既然是引用,因此可以将函数赋值给一个变量,也可以把函数作为一个参数...
    99+
    2022-06-04
    进阶 老生常谈 Python
  • python装饰器2:类装饰器
    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 本文是装饰器相关内容的第二篇,关于类装饰器。 "类装饰器"有两种解读方式:用来装饰类的装饰器;类作为装饰器装饰其它东西。你如何认为取决于你,两种说法都有出现在其它的文章中。我的...
    99+
    2023-01-30
    python
  • python 装饰器
    装饰器本质上是一个Python函数,它可以让其他函数在不雲要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面雲求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳...
    99+
    2023-01-30
    python
  • python装饰器
    什么是装饰器:   装饰器就是python中的一个语法糖。作用就是在不改动之前代码的情况下给某个函数增加相应想要增加的功能。 假设需求:   我在几个函数内分别放了一部电影,代码如下: 1 def mv1(): 2 print(...
    99+
    2023-01-30
    python
  • python-装饰器
    装饰器简介:给被装饰的函数在不更改代码的基础上增加新的功能;多个装饰器的执行顺序:从最靠近原始函数的装饰器开始执行,最后执行原始函数; 直接上个简单的例子就懂了: 一 最简单的装饰器:#!/usr/bin/python def deco(f...
    99+
    2023-01-31
    python
  • python装饰器1:函数装饰器详解
    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函数 方法 类 基础...
    99+
    2023-01-30
    详解 函数 python
  • Python装饰器-闭包与函数装饰器
    一、闭包在学习装饰器前,需要先了解闭包的概念。形成闭包的要点:函数嵌套将内部函数作为外部函数的返回值内部函数必须要使用到外部函数的变量下面以一个计算列表平均值的案例来讲解闭包:def make_average(): # 创建一个列表,用来保...
    99+
    2023-05-14
    Python 函数 装饰器
  • Python之装饰器
    在Python中一切皆对象,函数是一等对象。这意味着可以通过名字引用函数。>>> a=123 >>> a 123 >>> name='zeng' >>> name 'z...
    99+
    2023-01-31
    Python
  • python装饰器详解
            python中的装饰器(decorator)一般采用语法糖的形式,是一种语法格式。比如:@classmethod,@staticmethod,@property,@xxx.setter,@wraps(),@func_na...
    99+
    2023-09-01
    python
  • day20-python之装饰器
    1.装饰器 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import time 4 def cal(l): 5 start_time=time.time() ...
    99+
    2023-01-31
    python
  • python 装饰器理解
    在理解装饰器之前,先应该对闭包有个概念:所谓闭包,就是将组成函数的语句和这些语句的执行环境打包在一起时得到的对象,它的主要作用是封存上下文。这一特性可以巧妙的被用于现有函数的包装,从而为现有函数添加功能,这就是装饰器。装饰器的本质与作用装饰...
    99+
    2023-01-31
    python
  • Python装饰器(Decorate)使
    一、装饰器是什么?Python装饰器其实就是一个返回值为函数的高阶函数,其中至少嵌套一个函数(作为返回值返回)。二、装饰器工作原理。遵循编程的闭合原则,在不修改原函数代码的基础上增加功能,使用装饰器是一种很好的选择。装饰器工作基于以下两步完...
    99+
    2023-01-31
    Python Decorate
  • Python——装饰器(无参)
    装饰器装饰器可以叠加使用,执行是从下到上执行的无参装饰器 @logger1.它是一个语法糖2.函数作为它 的形参3.返回值也是一个函数4.可以使用 @function 方式,简化调用注意: 此处的装饰器的定义并不准确,只是方便理解装饰器和高...
    99+
    2023-01-31
    Python
  • python的装饰器decorator
    在python中编程碰到过这样一件事情,需要给大量的函数做相同的操作,这样每个函数都去实现一遍这个功能显然是浪费时间。#这是一个装饰器函数def DecoratorFunc(func):    #Function就是对传入的func函数的包...
    99+
    2023-01-31
    python decorator
  • Python带参装饰器
    装饰器(无参)  它是一个函数;  函数作为它的形参;  返回值也是一个函数;  可以使用@functionname方式,简化调用;装饰器和高阶函数  装饰器是高阶函数,但装饰器是对传入函数的功能的装饰(功能增强)import dateti...
    99+
    2023-01-31
    Python
  • Python 装饰器总结
    装饰器是高阶函数,装饰器是对传入函数的功能增强。 装饰器的副作用:原函数对象的属性都被替换了,而使用了装饰器,查看到的函数对象属性就变成装饰器的函数对象了,如果需要查被装饰的函数的属性?对用原函数的属性覆盖掉装饰器的属性。解决方法:通过co...
    99+
    2023-01-31
    Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作