python 装饰器

一、装饰器的本质
1、本质就是一个python函数,一个闭包;
2、可以让其他函数在不需要做任何的代码变动,也不改变其调用方式的前提下,增加额外的功能;
3、应用场景:插入日记,性能测试,事务代理,缓存等场景.

二、标准装饰器书写语法
def timer(f):
def inner(*args,**kwargs):#无敌传参 聚合
'''功能之前执行的代码'''
ret=f(*args,**kwargs) #执行参数 打散
'''功能执行后执行的代码'''
return ret #函数的返回值
return inner

使用@timer放置在函数的上一行给函数添加装饰器.
@timer  #func=timer(f)
            #1、执行time(f) -->inner;
            #2、func=inner
            #当 func()  -> inner() 执行内部函数
import time

#简单装饰器
def timer(f):
    def inner(*args,**kwargs):
        start_time=time.time()
        ret =f(*args,**kwargs)
        end_time=time.time()
        print('该代码的执行效率>>>%s'%(start_time-end_time))
        return ret
    return inner
@timer  #func=timer(f)
            #1、执行time(f) -->inner;
            #2、func=inner
            #当 func()  -> inner() 执行内部函数
def foo(a,b):
    time.sleep(1)
    print('这是一万行代码')
    return a+b
foo(12,45)
标准版本装饰器示例

三、带参数的装饰器(flag):控制装饰器是否执行装饰部分代码

  应用场景分析

假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?

一个一个的取消掉? 没日没夜忙活3天。。。

过两天你领导想通了,再让你加上。。。

  代码演示

核心分析

@outer(flag)
        #1、单纯执行outer(flag) -->timer
        #2、@与timer结合形成装饰器
        #3、foo=timer()
        #4、timer() -->inner
        #5、foo=inner

def foo(a,b):
import time

flag=True
def outer(flag):
    def timer(f):
        def inner(*args,**kwargs):
            if not flag:
                ret = f(*args, **kwargs)
                return ret
            else:
                start_time=time.time()
                ret =f(*args,**kwargs)
                end_time=time.time()
                print('该代码的执行效率>>>%s'%(start_time-end_time))
                return ret
        return inner
    return timer

@outer(flag)
        #1、单纯执行outer(flag) -->timer
        #2、@与timer结合形成装饰器
        #3、foo=timer()
        #4、timer() -->inner
        #5、foo=inner

def foo(a,b):
    time.sleep(1)
    print('这是一万行代码')
    return a+b

@outer(flag)
def foo2(a,b):
    time.sleep(1)
    print('这是二万行代码')
    return a+b

@outer(flag)
def foo3(a,b):
    time.sleep(1)
    print('这是三万行代码')
    return a+b

foo(10,20)
foo2(30,50)
foo3(17,28)
带flag参数的装饰器

四、多个装饰器装饰一个函数

   1、就近原则,越靠近函数的装饰器先装饰,之后的装饰器,装饰被装饰的函数。

import time

def swrap1(f):
    def inner(*args,**kwargs):
        print('来自装饰器1',1)
        f(*args,**kwargs)
        print('来自装饰器1',2)
        return
    return inner

def swrap2(f):
    def inner(*args,**kwargs):
        print('来自装饰器2>>>',1)
        f(*args,**kwargs)
        print('来自装饰器2>>>',2)
        return
    return inner

@swrap2 #func=swrap2(func) ->func=inner--1  ->inner--1=inner--2
@swrap1 #func=swrap1(func) ->func=原func func=inner--1 表示swrap1中的inner
def func(a,b):
    print('我是函数本身func')
func(10,20) #本质执行的是inner--2()
#2-1 1-1 本身 1-2 2-2
多装饰器装饰一个函数

五、登陆注册装饰器示例

dic_status = {
    'username': None,
    'status': False
}

def login(f):
    def inner():
        print(dic_status)

        if dic_status['status']==False:
            username=input("请输入用户名:")
            password=input("请输入密码:")
            with open('register','r',encoding='utf-8') as f1:
                for line in f1:
                    lst=line.strip().split('|')
                    if username.strip()==lst[0] and password.strip()==lst[1]:
                        print('登录成功')
                        dic_status['status']=True
                        dic_status['name']=username
                        ret = f()
                        """被装饰函数执行之后的操作"""
                        print(dic_status)
                        return ret
                else:
                    print("登录失败!")
                    print(dic_status)
                    return False
        else:
            ret = f()
            """被装饰函数执行之后的操作"""
            return ret
    return inner

@login
def article():
    print('欢迎登录文章页面')
@login
def diary():
    print('欢迎登录日记页面')
@login
def comment():
    print('欢迎登录评论页面')

article()

diary()

comment()
登陆装饰器示例

register文件

alex|123
wusir|456
简单存储的用户信息


原文地址:https://www.cnblogs.com/angle6-liu/p/10170988.html