装饰器

作者: Koelre | 来源:发表于2020-04-25 16:55 被阅读0次
    # !/usr/bin/python
    #-*- coding:utf-8 -*-
    
    '''示例1: 最简单的函数,表示调用了两次'''
    def myfun():
        print('hello')
    
    myfun()
    myfun()
    
    # ------------------------------------分割线--------------------------------------
    
    # 使用装饰函数在函数执行前和执行后分别附加额外功能
    '''示例2: 替换函数(装饰)
    装饰函数的参数是被装饰的函数对象,返回原函数对象
    装饰的实质语句: myfunc = deco(myfunc)'''
    def deco(func):
        print('before')
        func()
        print('after')
        return func
    
    def myfunc():
        print('myfunc called')
    
    myfune = deco(myfunc)
    myfune()
    myfune()
    
    # ------------------------------------分割线--------------------------------------
    
    # 使用语法糖@来装饰函数
    '''示例3: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
    但发现新函数只在第一次被调用,且原函数多调用了一次'''
    def deco(func):
        print('before')
        func()
        print('later')
        return func
    
    @deco
    def myfun():
        print('myfun,,,,')
    
    myfun()
    myfun()
    
    # ------------------------------------分割线--------------------------------------
    
    # 使用内嵌包装函数来确保每次新函数都被调用
    '''示例4: 使用内嵌包装函数来确保每次新函数都被调用,
    内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
    def deco(abc):
        def _deco():
            print('before...')
            abc()
            print('later...')
        
        return _deco
    
    @deco
    def cc():
        print('cc....')
    
    cc()
    cc()
    
    # ------------------------------------分割线--------------------------------------
    
    # 对带参数的函数进行装饰
    '''示例5: 对带参数的函数进行装饰,
    内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
    def deco(func):
        def _deco(a,b):
            print('before')
            func(a,b)
            print('after')
        return _deco
    
    @deco
    def myfun(a,b):
        print('my,,,,')
        return a+b
    
    myfun(1,2)
    myfun(3,4)
    
    # ------------------------------------分割线--------------------------------------
    
    # 对参数数量不确定的函数进行装饰
    '''示例6: 对参数数量不确定的函数进行装饰,
    参数用(*args, **kwargs),自动适应变参和命名参数'''
    def deco(func):
        def _deco(*args,**kwargs):
            print('before')
            func(*args,**kwargs)
            print('after')
        return _deco
    
    @deco
    def myfun1(a,b):
        print('myfun')
        return a+b
    
    @deco
    def myfun2(a,b,c):
        print('fun2...')
        return a+b+c
    
    myfun1(1,2)
    myfun2(1,2,3)
    
    # ------------------------------------分割线--------------------------------------
    
    # 让装饰器带参数
    # '''示例7: 在示例4的基础上,让装饰器带参数,
    # 和上一示例相比在外层多了一层包装。
    # 装饰函数名实际上应更有意义些'''
    def deco(arg):
        def _deco(func):
            def __deco():
                print('before')
                func()
                print('after')
            return __deco
        return _deco
    
    @deco('moudle1')
    def myfun():
        print('myfun,,,')
    
    @deco('moudle2')
    def myfun2():
        print('myfun222')
    
    myfun()
    myfun2()
    
    # ------------------------------------分割线--------------------------------------
    
    # 让装饰器带 类 参数
    '''示例8: 装饰器带类参数'''
    class locker:
        def __init__():
            print('locker __init__.........')
        
        @staticmethod
        def acquire():
            print('locker.acquire..... ')
        
        @staticmethod
        def release():
            print('locker.release...........')
        
    def deco(cls):
        def _deco(func):
            def __deco():
                print('bofore.....')
                cls.acquire()
                try:
                    return func
                finally:
                    cls.release()
            return __deco
        return _deco
    
    @deco(locker)
    def myfunc():
        print('myfunc.....')
    
    myfunc()
    myfunc()
    
    
    # ------------------------------------分割线--------------------------------------
    
    # 装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器
    '''mylocker.py: 公共类 for 示例9.py'''
    class mylocker:
        def __init__(self):
            print('__init__called')
        
        @staticmethod
        def acquire():
            print('mylocker.acquire.......')
        
        @staticmethod
        def unlock():
            print('mylocker.unlock..........')
        
    class lockerex(mylocker):
        @staticmethod
        def acquire():
            print('lockerex.acquire')
        
        @staticmethod
        def unlock():
            print('lockerex.unlock.....')
    
    def lockhelper(cls):
        '''cls 必须实现acquire和release静态方法'''
        def _deco(func):
            def __deco(*args,**kwargs):
                print('before..........')
                cls.acquire()
                try:
                    return func(*args,**kwargs)
                finally:
                    cls.unlock()
            return __deco
        return _deco
    
    
    # 调用
    class example:
        @lockhelper(mylocker)
        def myfunc(self):
            print('example.myfunc...........')
        
        @lockhelper(mylocker)
        @lockhelper(lockerex)
        def myfun2(self,a,b):
            print('example.myfun2.......')
            return a+b
        
    if __name__ == "__main__":
        a = example()
        a.myfunc()
        print(a.myfunc())
        print(a.myfun2(1,2))
        print(a.myfun2(3,4))
    
    
    
    

    *仅学习,侵删

    相关文章

      网友评论

          本文标题:装饰器

          本文链接:https://www.haomeiwen.com/subject/odgrnqtx.html