• 装饰器的基础知识点


    1.装饰器

      - 开放封闭原则:

      • 开放:对代码的扩展功能是开放的
      • 封闭:对源码的修改时封闭的 

      - 装饰器:在不该变原函数的代码以及调用方式的前提下,为其增加新的功能。

      - 装饰器就是一个函数,装饰器的本质就是一个闭包

      - 写代码测试一下index函数的执行效率

    import time

    def index(): """ 有许多代码""" time.sleep(2) # 模拟的网络延迟或者代码效率 print("欢迎登录博客园首页") def timmer(f): f = index def inner(): start_time = time.time() f() end_time = time.time() print(f'测试本函数的执行效率{end_time-start_time}') return inner index = timmer() index()

    分析代码的执行流程:

       - 标准装饰器

    import time
    
    
    def timmer(f):
        def inner(*args,**kwargs):
            start_time = time.time()
            v = f(*args,**kwargs)
            end_time = time.time()
            print(f'测试本函数的执行效率{end_time-start_time}')
            return v
        return inner
    
    @timmer  # index = timmer(index)
    def index():
        """ 有许多代码"""
        time.sleep(2)   #模拟的网络延迟或者代码效率
        print('欢迎登录博客园首页')
        return 666
    ret = index()
    print(ret)

    分析执行流程:

       - 装饰器的基本的框架

    def wrapper(func):
        def inner(*args,**kwargs):
            # 添加额外的功能:执行被装饰函数之前的操作
            ret = func(*args,**kwargs)
            # 添加额外的功能:执行被装饰函数之后的操作
               return ret
        return inner

    2.装饰器的应用场景:

      • 于用户认证
      • 面向对象的类方法:classmethod
      • 面向对象中的静态方法:staticmethod
      • django框架中的中间件
      • @crsf的认证
      • flask框架的路由  

    3.一个装饰装饰多个函数:

    status_dict = {"username": None, "status": False}
    
    
    def auth(f):
        """
        装饰器完成:访问被装饰函数之前,写一个登录认证的功能。
        登录成功:让其访问被装饰得函数,登录没有成功,不让访问。
        :param f:
        :return:
        """
    
        def inner(*args, **kwargs):
            """ 访问函数之前的操作,功能 """
            if status_dict["status"]:
                ret = f(*args, **kwargs)
                return ret
            else:
                username = input("请输入用户名").strip()
                password = input("请输入密码").strip()
                if username == "貂蝉" and password == "123":
                    print("登录成功")
                    status_dict['username'] = username
                    status_dict['status'] = True
                    ret = f(*args, **kwargs)
                    return ret
                else:
                    print("登录失败")
    
        return inner
    
    
    @auth
    def article():
        print('欢迎访问文章页面')
    
    
    @auth
    def comment():
        print('欢迎访问评论页面')
    
    
    @auth
    def dariy():
        print('欢迎访问日记页面')
    
    
    article()
    comment()
    dariy()

    4.多个装饰器装饰一个函数

    def wrapper(func):
        def inner(*args, **kwargs):
            print("is 123")
            func(*args, **kwargs)
            print("345")
    
        return inner
    
    
    def wrapper1(func):
        def inner1(*args, **kwargs):
            print("7")
            func(*args, **kwargs)
    
        return inner1
    
    
    def wrapper2(func):
        def inner2(*args, **kwargs):
            func(*args, **kwargs)
            print("15")
    
        return inner2
    
    
    @wrapper2
    @wrapper1
    @wrapper  # foo = wrapper(foo)
    def foo():  # 先执行里被装饰函数最近的那个装饰器
        print("is  foo")
    
    
    foo()
    
    # 执行结果为:
    7
    is 123
    is  foo
    345
    15

    分析执行流程:

     

     5.带参数的装饰器

    def outer(flag):
        def timer(func):
            def inner(*args,**kwargs):
                if flag:
                    print('''执行函数之前要做的''')
                re = func(*args,**kwargs)
                if flag:
                    print('''执行函数之后要做的''')
                return re
            return inner
        return timer
    
    @outer(False)
    def func():
        print(111)
    
    func()

    待续

  • 相关阅读:
    OpenERP 7.0 中文报表PDF乱码(WindowsXP)
    【转】CentOS 6.3 X64自动安装OpenERP 7.0脚本
    OE7设置菜单为什么这么少?
    PostgreSQL的备份和恢复
    PyPI镜像网站
    【转】Win 7 下源码运行OpenERP7.0
    OpenERP中的会计凭证
    OpenERP实施记录(14):收款处理
    OpenERP实施记录(13):出库处理
    intro.js 页面引导简单用法
  • 原文地址:https://www.cnblogs.com/zangyue/p/12056012.html
Copyright © 2020-2023  润新知