zoukankan      html  css  js  c++  java
  • 函数的装饰器

    装饰器的本质:一个闭包函数

      装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

    import time
    def timer(func):
        def inner():
            start = time.time()
            func()
            print(time.time() - start)
        return inner
    
    @timer   #==> func1 = timer(func1)
    def func1():
        print('in func1')
    
    
    func1()

    完整的装饰,万能的装饰

    def timmer(qqxing):   #timmer是装饰器的名字,传入的参数就是被装饰的函数
        def inner(*args,**kwargs):      #在装饰器中需要定义一个内部函数
            print('调用func之前')
            ret = qqxing(*args,**kwargs)      #被装饰的函数,并且要执行
            print('调用func之后')
            return ret
        return inner      #将内部函数的名字返回
    
    @timmer   #语法糖  func = timmer(func)
    def func(name):
        print('%s的公司好老板好同事好'%(name))
        return 1111111111
    
    ret = func('俊杰')
    print('result : %s'%ret)
    
    输出:
    调用func之前
    俊杰的公司好老板好同事好
    调用func之后
    result : 1111111111

    装饰器的固定结构:

    #装饰器的固定结构
    def wrapper(func):
        def inner(*args,**kwargs):
            """被装饰函数执行之前要添加的代码"""
            ret = func(*args,**kwargs)
            """被装饰函数执行之后要添加的代码"""
            return ret
        return inner

    多个装饰器装饰同一个函数

    有些时候,我们也会用到多个装饰器装饰同一个函数的情况。

    def wrapper1(func):
        def inner():
            print('wrapper1 ,before func')
            func()
            print('wrapper1 ,after func')
        return inner
    
    def wrapper2(func):
        def inner():
            print('wrapper2 ,before func')
            func()
            print('wrapper2 ,after func')
        return inner
    
    @wrapper2
    @wrapper1
    def f():
        print('in f')
    
    f()

    开放封闭原则

      1.对扩展是开放的

        为什么要对扩展开放呢?

        我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

      2.对修改是封闭的

        为什么要对修改封闭呢?

        就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

    装饰器完美的遵循了这个开放封闭原则。

    练习:

    #用装饰器实现,访问art或者dar函数,登陆一次之后,无需再次登录
    # art()
    # dar()

    flag = False
    
    def login(func):
        def inner(*args,**kwargs):
            global flag
            if flag == False:
                username = input('用户名:')
                password = input('密码:')
                if username == 'alex' and password == 'somebody':
                    print('登录成功')
                    flag = True
            if flag == True:
                ret = func(*args,**kwargs)
                return ret
        return inner
    
    @login
    def art():
        print('欢迎来到文章页')
    
    @login
    def dar():
        print('欢迎来到日记页')
    
    dar()
    art()
    
    输出:
    用户名:alex
    密码:somebody
    登录成功
    欢迎来到日记页
    欢迎来到文章页

    实现日志功能:

    def log(func):
        def inner(*args,**kwargs):
            print('你要调用%s函数了'%func.__name__)
            ret = func(*args,**kwargs)
            return ret
        return inner
    
    @log  #f1 = log(f1)
    def f1():
        print('f1')
    @log
    def f2():
        print('f2')
    
    #日志
    f1()
    f2()
    
    输出:
    你要调用f1函数了
    f1
    你要调用f2函数了
    f2
    import time
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            re = func(*args,**kwargs)
            print(time.time() - start)
            return re
        return inner
    
    @timer   #==> func2 = timer(func2)
    def func2(a):
        print('in func2 and get a:%s'%(a))
        return 'fun2 over'
    
    
    print(func2(2))  # 'fun2 over'
    
    输出:
    in func2 and get a:2
    0.0009996891021728516
    fun2 over

     装饰器进阶:

    进阶一:

    def outer(flag):
        def wrapper(func):
            def inner(*args,**kwargs):
                if flag:
                    print('执行%s之前我加了一个功能'%func.__name__)
                ret = func(*args,**kwargs)  #qqxing
                return ret
            return inner
        return wrapper
    @outer(True)      #qqxing = wrapper(qqxing)
    def qqxing():
        print('qqxing')
    
    @outer(False)    #wahaha  = wrapper(wahaha)
    def wahaha():
        print('wahaha')
    
    qqxing()
    wahaha()
    #2000
    #1000
    #1000
    
    # def outer(flag,flag2):
    #     def wrapper(func):
    #         def inner(*args,**kwargs):
    #             ret = func(*args,**kwargs)
    #             return ret
    #         return inner
    #     return wrapper
    #
    # @outer(True,False)   #带参数的装饰器 ==》@wrapper ==》func = wrapper(func) ==>  func == inner
    # def func():pass


    进阶二:

    def wrapper2(func):     #inner1
        def inner2(*args,**kwargs):
            print('in wrapper 2,before')
            ret = func(*args,**kwargs)   #inner1
            print('in wrapper 2,after')
            return ret
        return inner2
    def wrapper1(func):    #qqxing
        def inner1(*args,**kwargs):
            print('in wrapper 1,before')
            ret = func(*args,**kwargs)   #qqxing
            print('in wrapper 1,after')
            return ret
        return inner1
    
    
    @wrapper1       #qqxing = inner1
    @wrapper2       #qqxing = wrapper2(inner1)  = inner2
    def qqxing():
        print('qqxing')
    
    qqxing()    #inner2
    
    
    #login  一个实现login的装饰器
    #timmer 一个计算函数时间的装饰器
    
    #先登录,再计算时间
  • 相关阅读:
    java 三目运算符
    增强for 可以用于ArrayList
    shell SORT
    BASH if/while/until loop
    设置临时环境变量
    2015年创业中遇到的技术问题:121-130
    2015年创业中遇到的技术问题:121-130
    JDK8新特性之Lambda表达式
    使用Html5开发Android和iOS应用:HBuilder、Html5Plus、MUI
    使用Html5开发Android和iOS应用:HBuilder、Html5Plus、MUI
  • 原文地址:https://www.cnblogs.com/biluo/p/7789308.html
Copyright © 2011-2022 走看看