社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python函数式编程3(装饰器的深入理解)

水痕001 • 6 年前 • 397 次点击  
阅读 26

python函数式编程3(装饰器的深入理解)

一、什么是装饰器

  • 1、python中装饰器可以理解为AOP编程,有点类似Spring中的注解,在不改变原函数或类的基础上,对函数或类添加额外(自己需求补充)的功能。
  • 2、装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。
  • 3、有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
  • 4、比如我们要给每一个函数新增一个打印logger日志,我们就可以使用装饰器,在不修改原函数的前提下,新增功能又能做到代码的解耦。

二、装饰器的几个原则及学习装饰器必要的知识储备

三、装饰器的演变过程

  • 1、定义一个装饰器(计算函数执行时间)

    import time
    
    def timer(func):
    	def wrapper():
          start_time = time.time()
          res = func()
          end_time = time.time()
          print('程序运行时间:{0}'.format(end_time - start_time))
          return res
      return wrapper
    复制代码
  • 2、定义一个要执行的函数

    def foo():
        time.sleep(3)
        print('主函数')
    复制代码
  • 3、根据上面几个原则,我们来调用函数foo

    if __name__ == "__main__":
    		# 1.timer函数中传递函数foo进去
    		# 2.为了不改变函数的调用方式,将timer函数的返回值(函数)赋值给变量foo
        foo = timer(foo) # 前面foo是新定义的变量,timer中的foo是上面定义的foo函数
        foo() # timer是一个高阶函数,返回的是一个函数
    复制代码
  • 4、解答上面的代码

    • 1.定义的装饰器是一个高阶函数,被装饰的函数作为参数传递进去
    • 2.在满足装饰的原则下,我们把高阶函数执行后重新赋值给foo函数
    • 3.foo()函数的执行就没改变原有函数的调用方式
  • 5、使用装饰器**@**

上面第四点中2和3步骤在python中直接使用**@**语法糖来处理

@timer
def bar():
    time.sleep(2)
    print('主函数')
  
if __name__ == "__main__":
    bar()
复制代码

四、装饰器中传递参数

import time

def timer(func):
  def wrapper(*args, **kwargs):
      start_time = time.time()
      res = func(*args, **kwargs)
      end_time = time.time()
      print('执行时间:{0}'.format(end_time - start_time))
      return res

  return wrapper

@timer
def foo(name, gender):
  time.sleep(3)
  print(name)
  print(gender)

if __name__ == "__main__":
  foo('张三', gender='男')
复制代码

五、使用类来作装饰器

创建一个数据库操的log的装饰器

  • 1、具体实现代码

    from functools import wraps
    from datetime import datetime
    
    # 创建一个类的装饰器
    class Log(object):
        
    
    
        
    def __init__(self, logfile='log.log'):
            self.logfile = logfile
    
        def __call__(self, func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                self.writelog(*args, **kwargs)
                return func(*args, **kwargs)
    
            return wrapper
    
        # 把日志写到本地
        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 printLog(name, type):
        print('姓名:{0},type:{1}'.format(name, type))
    
    if __name__ == "__main__":
        printLog('张三', '查询')
        printLog('李四', '新增')
    复制代码
  • 2、执行结果(本地文件夹下多一个文件)

    2018-06-24 10:47:40 操作人:张三 进行了【查询】操作
    2018-06-24 10:47:40 操作人:李四 进行了【新增】操作
    复制代码
更多原著博文请参考

今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/XJwQThpQhM
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/26085
 
397 次点击