#函数装饰器即为不改变原函数代码的情况下为原函数添加额外功能。
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()
原文:http://www.cnblogs.com/cyalu/p/6023486.html