美文网首页
python07_函数装饰器

python07_函数装饰器

作者: 詹亮的小仓库 | 来源:发表于2020-03-11 18:08 被阅读0次

函数装饰器

  1. 为什么要用装饰器?

    装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

  2. 先定义两个个函数

         def addUser():
             print('添加用户成功!')
    
         def registUser():
             print('添加用户成功!')
    

    如果用户想要知道是哪个函数添加了用户,怎么办?(略...)

    改进方法

         def debug():
             import inspect
             caller_name = inspect.stack()[1][3]
             print("[DEBUG]: enter {}()".format(caller_name))
         
         def addUser():
             debug()
             print('添加用户成功!')
         
         def registUser():
             debug()
             print('添加用户成功!')
    

    但是如果再想要取消这个功能,则需要改变两个函数:addUser,registUser

     **装饰器的作用很明显**
         
         def debug(func):
             def wrapper():
                 print("[DEBUG]: enter {}()".format(func.__name__))
                 return func()
             return wrapper
         
         @debug
         def addUser():
             print('添加用户成功!')
             return 'ok'
         
         @debug
         def registUser():
             print('添加用户成功!')
    
  3. 装饰器传参

    参数先传给装饰器,装饰器传给函数

     def debug(func):
         def wrapper(name):
             print("[DEBUG]: enter {}()".format(func.__name__))
             func(name)
         return wrapper
     
     @debug
     def addUser(name):
         print('添加用户{0}成功!'.format(name))
     
     @debug
     def registUser(name):
         print('添加用户{0}成功!'.format(name))
     
     addUser('tom')
     registUser('jack')
    

    如果函数是有返回值的,则加上return 语句即可

     def debug(func):
         def wrapper(name):
             print("[DEBUG]: enter {}()".format(func.__name__))
             return func(name)  #此处加上return
         return wrapper
    
  4. 传递可变参数

     def debug(func):
         def wrapper(*args,**other):
             print("[DEBUG]: enter {}()".format(func.__name__))
             print(other)
             # 可以在此处对 args和other数据进行处理
             return func(args)
         return wrapper
     
     @debug
     def addUser(user):
         print('添加用户{0}成功!'.format(user))
         return user
     
     @debug
     def registUser(user):
         print('添加用户{0}成功!'.format(user))
         return user
     
     n1=addUser('tom',12,other={'gender': 'M', 'job': 'Engineer'})
     n2=registUser('jack')
    
  5. 最新版本

    最新版本的python导入了functools模块

     from functools import wraps
     def debug(func):
         @wraps(func)
         def wrapper(name):
             print("[DEBUG]: enter {}()".format(func.__name__))
             return func(name)  #此处加上return
         return wrapper
     @debug
     
     def show(s):
         print(s)
     
     show('ppyth')
    
  6. 带参数的装饰器

        from functools import wraps
        def debug(*text):
            def decorated(func):
                @wraps(func)
                def wrapper(name):
                    print("[DEBUG]: enter {}()".format(func.__name__))
                    return func(name)  # 此处加上return
        
                return wrapper
            return decorated
        
        @debug()  #此处的()不可以删略
        def show(s):
            print(s)
        
        show('ppyth')
    
  7. __call__()

    所有的函数都是可调用对象。
    一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法call()

     class Person(object):
         def __init__(self,name):
             self.name=name
     
         def __call__(self, *args, **kwargs):
             print('my name is ',self.name)
             print('my hobby is ',args)
     
     p1=Person('tom')
     
     p1('reading')
    

    所以,在Python中,函数也是对象,对象和函数的区别并不显著。

  8. 类装饰器(待续.....)

     from functools import wraps
     from datetime import datetime
     
     #类的装饰器写法,日志
     class log(object):
         def __init__(self, logfile='out.log'):
             self.logfile = logfile
     
         def __call__(self, func):
             @wraps(func)
             def wrapped_func(*args, **kwargs):                     
                 self.writeLog(*args, **kwargs)    # 先调用 写入日志         
                 return func(*args, **kwargs)     # 正式调用主要处理函数       
             return wrapped_func
     
        #写入日志    
         def writeLog(self, *args, **kwargs):
             time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
             log_str = time+' 操作人:{0[0]} 进行了【{0[1]}】操作'.format(args)           
             with open(self.logfile, 'a',encoding='utf8') as file:
                 file.write(log_str + '\n')
     
     @log()
     def myfunc(name,age):
         print('姓名:{0},年龄:{1}'.format(name,age))
     
     if __name__ == '__main__':
         myfunc('小白', '查询')
         myfunc('root', '添加人员')
         myfunc('小小', '修改数据')
    

相关文章

  • python07_函数装饰器

    函数装饰器 为什么要用装饰器?装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前...

  • 装饰器

    [TOC] 函数 函数定义 函数调用 高阶函数 嵌套函数 装饰器 装饰器=高阶函数+嵌套函数 基础装饰器 假设有一...

  • 031 Python语法之装饰器

    装饰器 装饰器格式 装饰器 本质是函数 功能是用于装饰其他函数,为其他函数附加其它功能 装饰器的原则 不能修改被装...

  • python装饰器2018-11-19

    装饰器也是个函数 装饰器有参数,参数是函数 装饰器有内嵌函数 装饰器有返回值,返回值是内嵌函数 装饰器使用时直接挂...

  • Python day30_闭包与装饰器

    闭包 装饰器 装饰器结论: 一个装饰器一个函数了解 二个装饰器装饰一个函数图解大法 二个装饰器装饰器一个函数内存图...

  • python——装饰器详解

    一、装饰器概念 1、装饰器 装饰器:一种返回值也是一个函数的函数,即装饰器。 2、装饰器目的 装饰器的目的:装饰器...

  • Python 进阶之装饰器

    1. 最基础的装饰器 装饰器基本的套路: 函数进,函数出. 函数名要作为参数传入装饰器,函数出: 装饰器要返回一个...

  • 装饰器

    装饰器 为了动态拓展函数,而不去破坏原函数的调用,产生了装饰器。通常使用装饰器给函数加log。 单层装饰器 以上是...

  • python之装饰器模版

    装饰器的作用:装饰器即可以装饰函数也可以装饰类。装饰器的原理:函数也是对象 1.定义装饰器 2.使用装饰器假设de...

  • Flask 视图和路由的进阶技能

    视图装饰器 Python 装饰器是用于转换其它函数的函数。当一个装饰的函数被调用的时候,装饰器也会被调用。接着装饰...

网友评论

      本文标题:python07_函数装饰器

      本文链接:https://www.haomeiwen.com/subject/xgjhjhtx.html