装饰器的基础知识点

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()

 

待续

posted @ 2019-12-17 18:14  菜鸟学小白  阅读(243)  评论(0编辑  收藏  举报
ヾ(≧O≦)〃嗷~