转自http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html
第一步:最简单的函数,准备附加额外功能
[root@python day4]# cat dec1.py #!/usr/bin/env python def myfunc(): print "myfunc() called." myfunc()
第二步:使用装饰函数在函数执行前和执行后分别附加额外功能
[root@python day4]# cat dec1.py #!/usr/bin/env python def myfunc(): print "myfunc() called." def deco(func): print "beforce myfunc() called." func() print "after mufunc() called." return func myfunc = deco(myfunc) myfunc() #执行结果 [root@python day4]# python dec1.py beforce myfunc() called. myfunc() called. after mufunc() called. myfunc() called.
第三步:使用语法糖@来装饰函数
#!/usr/bin/env python def deco(func): #定义好装饰器 print "beforce myfunc() called." func() print "after mufunc() called." return func @deco #引用装饰器 def myfunc(): print "myfunc() called." myfunc() #执行结果 [root@python day4]# python dec1.py beforce myfunc() called. myfunc() called. after mufunc() called. myfunc() called.
第四步:使用内嵌包装函数来确保每次新函数都被调用
[root@python day4]# cat dec1.py #!/usr/bin/env python def deco(func): def _deco(): print "before myfunc() called." func() print "after myfunc() called." return _deco @deco def myfunc(): print "myfunc called." return "ok" myfunc() #执行结果 [root@python day4]# python dec1.py before myfunc() called. myfunc called. after myfunc() called.
第五步:对带参数的函数进行装饰
[root@python day4]# cat dec1.py #!/usr/bin/env python def deco(func): def _deco(a,b): print "before myfunc() called." ret = func(a,b) print "after mufunc() called. result: %s" % ret return ret return _deco @deco def myfunc(a,b): print "myfunc(%s,%s) called." % (a,b) return a + b myfunc(3,4) #执行结果 [root@python day4]# python dec1.py before myfunc() called. myfunc(3,4) called. after mufunc() called. result: 7
第六步:对参数数量不确定的函数进行装饰
[root@python day4]# cat dec2.py #!/usr/bin/env python def deco(func): def _deco(*args,**kwargs): print "before %s called." % func.__name__ ret = func(*args,**kwargs) print "after %s called. result: %s" % (func.__name__,ret) return ret return _deco @deco def myfunc(a,b): print "myfunc(%s,%s) called." % (a,b) return a + b @deco def myfunc2(a,b,c): print "myfunc2(%s,%s,%s) called." % (a,b,c) return a + b + c myfunc(1,2) myfunc2(3,4,5) #执行结果 [root@python day4]# python dec2.py before myfunc called. myfunc(1,2) called. after myfunc called. result: 3 before myfunc2 called. myfunc2(3,4,5) called. after myfunc2 called. result: 12
第七步:让装饰器带参数
[root@python day4]# cat dec3.py #!/usr/bin/env python 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() [root@python day4]# python dec3.py before myfunc called [mymodule]. myfunc() called. after myfunc called [mymodule]. before myfunc2 called [module2]. myfunc2() called. after myfunc2 called [module2].
第八步:让装饰器带 类 参数
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()
第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器
class mylocker: def __init__(self): print("mylocker.__init__() called.") @staticmethod def acquire(): print("mylocker.acquire() called.") @staticmethod def unlock(): print(" mylocker.unlock() called.") class lockerex(mylocker): @staticmethod def acquire(): print("lockerex.acquire() called.") @staticmethod def unlock(): print(" lockerex.unlock() called.") def lockhelper(cls): '''cls 必须实现acquire和release静态方法''' def _deco(func): def __deco(*args, **kwargs): print("before %s called." % func.__name__) cls.acquire() try: return func(*args, **kwargs) finally: cls.unlock() return __deco return _deco # -*- coding:gbk -*- '''示例9: 装饰器带类参数,并分拆公共类到其他py文件中 同时演示了对一个函数应用多个装饰器''' from mylocker import * class example: @lockhelper(mylocker) def myfunc(self): print(" myfunc() called.") @lockhelper(mylocker) @lockhelper(lockerex) def myfunc2(self, a, b): print(" myfunc2() called.") return a + b if __name__=="__main__": a = example() a.myfunc() print(a.myfunc()) print(a.myfunc2(1, 2)) print(a.myfunc2(3, 4))