zoukankan      html  css  js  c++  java
  • 装饰器之起飞版

    原则:

    装饰器去装饰一个函数 :不改变被装饰函数的源代码,不改变被装饰函数的调用方式

    # 基础形态    **********这才是终极版************

    def wrapper(func): # func函数对象 ---> 被装饰对象 # *args, **kwargs用于接收被装饰对象的参数 def inner(*args, **kwargs): # 在调用被装饰对象前 添加新功能 @beforemethod res = func(*args, **kwargs) # 被装饰函数 # 在调用被装饰对象后 添加新功能 @aftermethod return res return inner def sleep(): print('111') sleep = wrapper(sleep) # = return inner 即sleep = inner = @wrapper sleep() =inner() # sleep() = 装饰器里面的inner() , #可以debug看一下

    #也可以写成
    @wrapper
    sleep()

    总结:1.被装饰装饰过的函数:调用被装饰函数时  就是在调用装饰器里面的inner()       

               2. 可以在被装饰对象前加新功能,也可以在被装饰函数后面加新功能

               3.不改变被装饰函数的调用方式:1.不改变原函数名 2.不改变被调用函数的参数

               4. 如果装饰中没有增加任何新功能只有被装饰的函数,这里叫作空装饰器,调用被空装饰其装饰的函数时,相当于直接执行被装饰的函数

               5. 当装饰器中没有被装饰的函数res = func(*args,**kwargs) 时,只会执行装饰器中的代码,不会再调用被装饰的函数         

    def wrapper1(func):
        def inner1(*args, **kwargs):
            print('1---start')
            # 被裝飾對象在調用時,如果還有其他裝飾器,會先執行其他裝飾器中的inner
            # inner2
            # res = func(*args, **kwargs)    被装饰函数
            print('1---end')
            # return res
    
        return inner1
    
    @wrapper1  # index《---inner1 = wrapper1(inner2)
    # @wrapper2  # inner2 = wrapper2(inner3)
    # @wrapper3  # inner3 = wrapper3(index)
    def index():  # 被裝飾對象   # inner1 ---》
        print('from index...')
    index()
    
    1---start
    from index...
    1---end

    2.叠加装饰器

    def wrapper1(func):
        def inner1(*args, **kwargs):
            print('1---start')
            # 被裝飾對象在調用時,如果還有其他裝飾器,會先執行其他裝飾器中的inner
            # inner2
            res = func(*args, **kwargs)   
            print('1---end')
            return res
        return inner1
    
    
    def wrapper2(func):
        def inner2(*args, **kwargs):
            print('2---start')
            res = func(*args, **kwargs)
            print('2---end')
            return res
        return inner2
    
    
    def wrapper3(func):
        def inner3(*args, **kwargs):
            print('3---start')
            res = func(*args, **kwargs)
            print('3---end')
            return res
        return inner3
    
    '''
    叠加裝飾器的裝飾順序與執行順序:
        - 裝飾順序: 调用wrapper装饰器拿到返回值inner
            由下往上裝飾
            
        - 執行順序: 调用装饰过后的返回值inner
            由上往下執行
    '''
    
    
    @wrapper1  # index《---inner1 = wrapper1(inner2)
    @wrapper2  # inner2 = wrapper2(inner3)
    @wrapper3  # inner3 = wrapper3(index)
    def index():  # 被裝飾對象   # inner1 ---》
        print('from index...')
    index()

    >>> 1---start
    >>> 2---start
    >>> 3---start
    >>> from index...
    >>> 3---end
    >>> 2---end
    >>> 1---end

    总结:从下往上装饰,从上往下执行,一层包一层

    3.有参装饰器  @user_auth('svip')   加一层函数传参去判断 用户类型

    # 有参装饰器
    def user_auth(user_role):  # 'SVIP'
        def wrapper(func):
            def inner(*args, **kwargs):
                if user_role == 'SVIP':
    print('前超级用户')
    # 添加超级用户的功能 res = func(*args, **kwargs)
    print('后超级用户')
    return res elif user_role == '普通用户': print('普通用户') # 添加普通用户的功能 res = func(*args, **kwargs) return res return inner return wrapper # 被装饰对象 # @user_auth('SVIP') wrapper = user_auth('普通用户') # @user_auth('SVIP') # wrapper = user_auth('普通用户') def index(): print('被装饰函数') index()


    >>> 前超级用户
    >>> 被装饰函数
    >>> 后超级用户
  • 相关阅读:
    让你少奋斗10年的工作经验
    POJ Exponentiation解题
    数据结构树和二叉树
    语句摘录
    ACM解题报告格式
    编程规范
    数据结构图
    Java学习之二Java反射机制
    使用Python正则表达式提取搜索结果中的站点
    toj 1702 A Knight's Journey
  • 原文地址:https://www.cnblogs.com/bigbox/p/11854394.html
Copyright © 2011-2022 走看看