1》在函数执行前和执行后分别附加其他的功能
def demo(func):#装饰函数的参数是被装饰的函数对象,返回原函数对象
print("before myfunc() is called.")
func()
print("after myfunc() is called.")
return func
def myfunc():
print 'myfunc() is called!'
myfunc()#调用myfunc函数本身
print '------------------'
myfunc=demo(myfunc)#该语句就是装饰的实质语句!!
print '------------------'
myfunc()#由于demo函数返回的是原函数本身,此处调用的依然是myfunc函数本身
运行结果:
2》使用语法糖@来装饰函数
def demo(func):#装饰函数的参数是被装饰的函数对象,返回原函数对象
print("before myfunc() is called.")
func()
print("after myfunc() is called.")
return func
@demo #程序运行到此处时,以myfunc为实参转去调用demo函数,将demo的返回值赋给myfunc
def myfunc():
print 'myfunc() is called!'
print '-----------'
myfunc()#由于demo函数返回的是原函数本身,此处调用的依然是myfunc函数本身
运行结果:
3》使用内嵌包装函数来确保新函数被调用
def deco(func):
def _deco():#内嵌包装函数的形参和返回值与原函数相同
print("before myfunc() called.")
result=func()
print("after myfunc() called.")
return result
return _deco #装饰函数返回 内嵌包装函数对象
@deco
def myfunc():
print("myfunc() called.")
return 'ok'
print myfunc()#实际上,调用的是_demo函数
运行结果:
4》对带参数的函数进行装饰
def deco(func):
def _deco(a, b):#内嵌包装函数的形参和返回值与原函数相同
print("before myfunc() called.")
result = func(a, b)
print("after myfunc() called.")
return result
return _deco#装饰函数返回内嵌包装函数对象
@deco
def myfunc(a,b):
print("myfunc(%s,%s) called." % (a, b))
return a + b
print myfunc(1, 2)#实际上,调用的是_demo函数
运行结果:
5》对参数数量不确定的函数进行装饰
def deco(func):
def _deco(*args, **kwargs):#参数用(*args,**kwargs),自动适应变参和命名参数
print("before %s called." % func.__name__)
result=func(*args, **kwargs)
print args
print kwargs
print("after %s called." % func.__name__)
return result
return _deco
@deco
def myfunc(a,b):
print("myfunc() called.")
return a+b
@deco
def myfunc1(*args, **kwargs):
print("myfunc1() called.")
print myfunc(1, 2)
print '-----------'
print myfunc1(3, 4, 5,a=1,b=2)
运行结果:
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("mymodule1")
def myfunc1():
print("myfunc2() called.")
myfunc()
myfunc1()
运行结果:
7》让装饰器带 类 参数
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静态方法
因为装饰器中要调用acquire和release方法,所以类中要定义这2个方法
之所以定义成静态方法,是因为静态方法可以通过类名来调用,不需要生成实例
'''
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()
运行结果:
8》让装饰器带函数参数
def Filter(before_func,after_func):
print before_func
print after_func
def outer(main_func):
print main_func
def wrapper(request,kargs):
before_result=before_func(request,kargs)
if(before_result!=None):
return before_result;
main_result=main_func(request,kargs)
if(main_result!=None):
return main_result;
after_result=after_func(request,kargs)
if(after_result!=None):
return after_result;
return wrapper
return outer
def before(request,kargs):
print request,kargs,'之前!'
def after(request,kargs):
print request,kargs,'之后!'
@Filter(before,after)
def main(request,kargs):
print request,kargs
main('hello','python')
print main
运行结果:
hello python 之前!
hello python
hello python 之后!
mylocker.py文件:
#!/usr/bin/env python
#coding:utf-8
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是 类
'''cls必须实现acquire和unlock静态方法,静态方法可以通过类名来调用,不需要实例'''
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
decorator.py文件:
#!/usr/bin/env python
#coding:utf-8
from mylocker import *
class example:
def __init__(self):
print '生成一个example类的实例!!'
@lockhelper(mylocker)
def myfunc(self):
print("myfunc() called.")
@lockhelper(mylocker)
@lockhelper(lockerex)
def myfunc1(self, a, b):
print("myfunc1() called.")
return a + b
if __name__=="__main__":
a = example()
print a
print '-------------'
print a.myfunc()
print '-------------'
print a.myfunc1(1, 2)
运行decorator.py文件,结果:
生成一个example类的实例!!
<__main__.example instance at 0x02AA2B48>
-------------
before myfunc called.
mylocker.acquire() called.
myfunc() called.
mylocker.unlock() called.
None
-------------
before __deco called.
mylocker.acquire() called.
before myfunc1 called.
lockerex.acquire() called.
myfunc1() called.
lockerex.unlock() called.
mylocker.unlock() called.
3
如果你感觉 “对一个函数应用多个装饰器” 不容易理解,没关系,上边的例子确实有点复杂,
这儿有一个简单的例子可以帮助你理解:python 对一个函数应用多个装饰器