Python装饰器学习(九步入门)
2016-09-04 08:41
447 查看
原文链接:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html
本文对原文略有改动。。。增加了自己的理解。。。
装饰器其实也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标识符。
1》在函数执行前和执行后分别附加其他的功能
myfunc() is called!
------------------
before myfunc() is called.
myfunc() is called!
after myfunc() is called.
------------------
myfunc() is called!
2》使用语法糖@来装饰函数
before myfunc() is called.
myfunc() is called!
after myfunc() is called.
-----------
myfunc() is called!
3》使用内嵌包装函数来确保新函数被调用
before myfunc() called.
myfunc() called.
after myfunc() called.
ok
4》对带参数的函数进行装饰
before myfunc() called.
myfunc(1,2) called.
after myfunc() called.
3
5》对参数数量不确定的函数进行装饰
before myfunc called.
myfunc() called.
(1, 2)
{}
after myfunc called.
3
-----------
before myfunc1 called.
myfunc1() called.
(3, 4, 5)
{'a': 1, 'b': 2}
after myfunc1 called.
None
6》让装饰器带参数
before myfunc called [mymodule].
myfunc() called.
after myfunc called [mymodule].
before myfunc1 called [mymodule1].
myfunc2() called.
after myfunc1 called [mymodule1].
7》让装饰器带 类 参数
before myfunc called [__main__.locker].
locker.acquire() called.(这是静态方法)
myfunc() called.
locker.release() called.(不需要对象实例)
8》让装饰器带函数参数
<function before at 0x02AC7BF0>
<function after at 0x02AC7C30>
<function main at 0x02AC7CF0>
hello python 之前!
hello python
hello python 之后!
<function wrapper at 0x02AC7D30>
9》装饰器带类参数,并分拆公共类到mylocker.py文件中,同时演示了对一个函数应用多个装饰器。。。
mylocker.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 对一个函数应用多个装饰器
虽然一个函数上面可以有多个装饰器,这种情况一般不推荐使用,因为这种情况下,程序的维护比较困难。。。
(完)
本文对原文略有改动。。。增加了自己的理解。。。
装饰器其实也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标识符。
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函数本身运行结果:
myfunc() is called!
------------------
before myfunc() is called.
myfunc() is called!
after myfunc() is called.
------------------
myfunc() is called!
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函数本身运行结果:
before myfunc() is called.
myfunc() is called!
after myfunc() is called.
-----------
myfunc() is called!
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函数运行结果:
before myfunc() called.
myfunc() called.
after myfunc() called.
ok
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函数运行结果:
before myfunc() called.
myfunc(1,2) called.
after myfunc() called.
3
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)运行结果:
before myfunc called.
myfunc() called.
(1, 2)
{}
after myfunc called.
3
-----------
before myfunc1 called.
myfunc1() called.
(3, 4, 5)
{'a': 1, 'b': 2}
after myfunc1 called.
None
6》让装饰器带参数
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()运行结果:
before myfunc called [mymodule].
myfunc() called.
after myfunc called [mymodule].
before myfunc1 called [mymodule1].
myfunc2() called.
after myfunc1 called [mymodule1].
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()运行结果:
before myfunc called [__main__.locker].
locker.acquire() called.(这是静态方法)
myfunc() called.
locker.release() called.(不需要对象实例)
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运行结果:
<function before at 0x02AC7BF0>
<function after at 0x02AC7C30>
<function main at 0x02AC7CF0>
hello python 之前!
hello python
hello python 之后!
<function wrapper at 0x02AC7D30>
9》装饰器带类参数,并分拆公共类到mylocker.py文件中,同时演示了对一个函数应用多个装饰器。。。
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 _decodecorator.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 对一个函数应用多个装饰器
虽然一个函数上面可以有多个装饰器,这种情况一般不推荐使用,因为这种情况下,程序的维护比较困难。。。
(完)
相关文章推荐
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门) 分类: python学习 2015-03-06 14:26 90人阅读 评论(0) 收藏
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- [转载]Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- Python装饰器学习(九步入门)
- [Python入门及进阶笔记00]-写在前面(目录/书籍/学习路线/其他)
- Python的入门学习及开发环境的搭建
- Python学习笔记 01 快速入门
- Debian Linux下的Python学习——入门