zoukankan      html  css  js  c++  java
  • 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
    简单存储的用户信息


  • 相关阅读:
    Win10 VS2013 PCL1.8.1和依赖项VTK8.0.1, QHuall(2.15.2), FLANN1.9.1,Boost1.59.0,Zbil1.2.11和libPNG1.6.34编译安装
    Boost log中的几个问题
    Linux 使用静态库注意事项
    Windows中lib和DLL区别和使用
    CMake: ELF文件加载动态库的位置
    CMake 默认编译、链接选项
    ld 链接选项-L,-rpath-link,-rpath
    动态库的链接和链接选项-L,-rpath-link,-rpath
    Linux共享对象之编译参数 -fPIC
    ny509 因子和阶乘
  • 原文地址:https://www.cnblogs.com/angle6-liu/p/10170988.html
Copyright © 2011-2022 走看看