• python装饰器


    #函数装饰器即为不改变原函数代码的情况下为原函数添加额外功能。

     1 #第一步,根据需求我们可以把原函数当初装饰函数的参数传进去,然后再执行原函数之前或之后添加需要的额外功能。
     2 def deco(func):
     3     print("before myfunc() called.")
     4     func()
     5     print("  after myfunc() called.")
     6     return func
     7 
     8 def myfunc():
     9     print(" myfunc() called.")
    10 
    11 myfunc = deco(myfunc)
    12 
    13 myfunc()
    14 
    15 Result:
    16     before myfunc() called.
    17      myfunc() called.
    18       after myfunc() called.
    19      myfunc() called.  
    20 #我们发现原函数被执行了俩次,因为第一次是myfunc=deco(myfunc)的时候就已经执行了。后面我们调用的myfunc()其实是原函数又被调用了一次。

    第二步,我们加上装饰器的语法糖@,可以达到同样的目的。

    def deco(func):
        print("before myfunc() called.")
        func()
        print("  after myfunc() called.")
        return func
    @deco
    def myfunc():
        print(" myfunc() called.")
    
    # myfunc = deco(myfunc)  #等同于原函数上加上@deco
    
    myfunc()    
    
    Result:
        before myfunc() called.
         myfunc() called.
          after myfunc() called.
         myfunc() called.
    
    
    第三步,我们要解决@deco自动执行函数的问题,这样保证我们myfunc()调用的是装饰后的函数。

    '''
    示例4: 使用内嵌包装函数来确保每次新函数都被调用, 内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象''' def deco(func): def _deco(): print("before myfunc() called.") func() print(" after myfunc() called.") # 不需要返回func,实际上应返回原函数的返回值 return _deco @deco def myfunc(): print(" myfunc() called.") myfunc() Result: before myfunc() called. myfunc() called. after myfunc() called.

    好了。装饰器就这样产生了。下面我们示例带参数的和一些常用装饰器的用法。

    '''示例1: 对带参数的函数进行装饰,
    内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
     
    def deco(func):
        def _deco(a, b):
            print("before myfunc() called.")
            ret = func(a, b)
            print("  after myfunc() called. result: %s" % ret)
            return ret
        return _deco
     
    @deco
    def myfunc(a, b):
        print(" myfunc(%s,%s) called." % (a, b))
        return a + b
     
    myfunc(1, 2)
    myfunc(3, 4)
    
    
    '''示例2: 在示例4的基础上,让装饰器带参数,
    和上一示例相比在外层多了一层包装。
    装饰函数名实际上应更有意义些'''
     
    def deco(arg):
        def _deco(func):
            def __deco():
                print("before %s called [%s]." % (func.__name__, arg))
                func()
                print("  after %s called [%s]." % (func.__name__, arg))
            return __deco
        return _deco
     
    @deco("mymodule")
    def myfunc():
        print(" myfunc() called.")
     
    @deco("module2")
    def myfunc2():
        print(" myfunc2() called.")
     
    myfunc()
    myfunc2()
    
    
    '''示例3: 装饰器带类参数'''
     
    class locker:
        def __init__(self):
            print("locker.__init__() should be not called.")
             
        @staticmethod
        def acquire():
            print("locker.acquire() called.(这是静态方法)")
             
        @staticmethod
        def release():
            print("  locker.release() called.(不需要对象实例)")
     
    def deco(cls):
        '''cls 必须实现acquire和release静态方法'''
        def _deco(func):
            def __deco():
                print("before %s called [%s]." % (func.__name__, cls))
                cls.acquire()
                try:
                    return func()
                finally:
                    cls.release()
            return __deco
        return _deco
     
    @deco(locker)
    def myfunc():
        print(" myfunc() called.")
     
    myfunc()
    myfunc()
    
    51_陆雅亮
  • 相关阅读:
    StringBuffer与Stringbuilder
    String与其他类型的转换
    创建多进程的方法
    8.进程
    克隆虚拟机
    初探12306售票算法(二)-java代码实践
    初探12306售票算法(一)- 理论
    手机上mcd程序耗电异常问题相关
    vue版app上下拉加载
    css基础
  • 原文地址:https://www.cnblogs.com/cyalu/p/6023486.html
Copyright © 2020-2023  润新知