【转】九步学习python装饰器

本篇日志来自:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 纯转,只字未改。只是为了学习一下装饰器。其实现在也是没有太看明白,对于装饰器我就是用的时候找例子,能蒙对,但是用过之后一段时间就忘了。还是用的少。有空应该好好看一看的,包括闭包。对于各种现代编程语言来说闭包都是很重要的。在这里先谢过原作者,如有侵权请告知。

=-=-=-=-=-=-=-=-=-=-一条不怎么华丽的分隔线-=-=-=-=-=-=-=-=-=-=

这是在Python学习小组上介绍的内容,现学现卖、多练习是好的学习方式。

第一步:最简单的函数,准备附加额外功能

1 # -*- coding:gbk -*-
2 ‘‘‘示例1: 最简单的函数,表示调用了两次‘‘‘
3
4 def myfunc():
5     print("myfunc() called.")
6
7 myfunc()
8 myfunc()

第二步:使用装饰函数在函数执行前和执行后分别附加额外功能

 1 # -*- coding:gbk -*-
 2 ‘‘‘示例2: 替换函数(装饰)
 3 装饰函数的参数是被装饰的函数对象,返回原函数对象
 4 装饰的实质语句: myfunc = deco(myfunc)‘‘‘
 5
 6 def deco(func):
 7     print("before myfunc() called.")
 8     func()
 9     print("  after myfunc() called.")
10     return func
11
12 def myfunc():
13     print(" myfunc() called.")
14
15 myfunc = deco(myfunc)
16
17 myfunc()
18 myfunc()

第三步:使用语法糖@来装饰函数

 1 # -*- coding:gbk -*-
 2 ‘‘‘示例3: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
 3 但发现新函数只在第一次被调用,且原函数多调用了一次‘‘‘
 4
 5 def deco(func):
 6     print("before myfunc() called.")
 7     func()
 8     print("  after myfunc() called.")
 9     return func
10
11 @deco
12 def myfunc():
13     print(" myfunc() called.")
14
15 myfunc()
16 myfunc()

第四步:使用内嵌包装函数来确保每次新函数都被调用

 1 # -*- coding:gbk -*-
 2 ‘‘‘示例4: 使用内嵌包装函数来确保每次新函数都被调用,
 3 内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象‘‘‘
 4
 5 def deco(func):
 6     def _deco():
 7         print("before myfunc() called.")
 8         func()
 9         print("  after myfunc() called.")
10         # 不需要返回func,实际上应返回原函数的返回值
11     return _deco
12
13 @deco
14 def myfunc():
15     print(" myfunc() called.")
16     return ‘ok‘
17
18 myfunc()
19 myfunc()

第五步:对带参数的函数进行装饰

 1 # -*- coding:gbk -*-
 2 ‘‘‘示例5: 对带参数的函数进行装饰,
 3 内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象‘‘‘
 4
 5 def deco(func):
 6     def _deco(a, b):
 7         print("before myfunc() called.")
 8         ret = func(a, b)
 9         print("  after myfunc() called. result: %s" % ret)
10         return ret
11     return _deco
12
13 @deco
14 def myfunc(a, b):
15     print(" myfunc(%s,%s) called." % (a, b))
16     return a + b
17
18 myfunc(1, 2)
19 myfunc(3, 4)

第六步:对参数数量不确定的函数进行装饰

 1 # -*- coding:gbk -*-
 2 ‘‘‘示例6: 对参数数量不确定的函数进行装饰,
 3 参数用(*args, **kwargs),自动适应变参和命名参数‘‘‘
 4
 5 def deco(func):
 6     def _deco(*args, **kwargs):
 7         print("before %s called." % func.__name__)
 8         ret = func(*args, **kwargs)
 9         print("  after %s called. result: %s" % (func.__name__, ret))
10         return ret
11     return _deco
12
13 @deco
14 def myfunc(a, b):
15     print(" myfunc(%s,%s) called." % (a, b))
16     return a+b
17
18 @deco
19 def myfunc2(a, b, c):
20     print(" myfunc2(%s,%s,%s) called." % (a, b, c))
21     return a+b+c
22
23 myfunc(1, 2)
24 myfunc(3, 4)
25 myfunc2(1, 2, 3)
26 myfunc2(3, 4, 5)

第七步:让装饰器带参数

 1 # -*- coding:gbk -*-
 2 ‘‘‘示例7: 在示例4的基础上,让装饰器带参数,
 3 和上一示例相比在外层多了一层包装。
 4 装饰函数名实际上应更有意义些‘‘‘
 5
 6 def deco(arg):
 7     def _deco(func):
 8         def __deco():
 9             print("before %s called [%s]." % (func.__name__, arg))
10             func()
11             print("  after %s called [%s]." % (func.__name__, arg))
12         return __deco
13     return _deco
14
15 @deco("mymodule")
16 def myfunc():
17     print(" myfunc() called.")
18
19 @deco("module2")
20 def myfunc2():
21     print(" myfunc2() called.")
22
23 myfunc()
24 myfunc2()

第八步:让装饰器带 类 参数

 1 # -*- coding:gbk -*-
 2 ‘‘‘示例8: 装饰器带类参数‘‘‘
 3
 4 class locker:
 5     def __init__(self):
 6         print("locker.__init__() should be not called.")
 7
 8     @staticmethod
 9     def acquire():
10         print("locker.acquire() called.(这是静态方法)")
11
12     @staticmethod
13     def release():
14         print("  locker.release() called.(不需要对象实例)")
15
16 def deco(cls):
17     ‘‘‘cls 必须实现acquire和release静态方法‘‘‘
18     def _deco(func):
19         def __deco():
20             print("before %s called [%s]." % (func.__name__, cls))
21             cls.acquire()
22             try:
23                 return func()
24             finally:
25                 cls.release()
26         return __deco
27     return _deco
28
29 @deco(locker)
30 def myfunc():
31     print(" myfunc() called.")
32
33 myfunc()
34 myfunc()

第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器

 1 # -*- coding:gbk -*-
 2 ‘‘‘示例9: 装饰器带类参数,并分拆公共类到其他py文件中
 3 同时演示了对一个函数应用多个装饰器‘‘‘
 4
 5 from mylocker import *
 6
 7 class example:
 8     @lockhelper(mylocker)
 9     def myfunc(self):
10         print(" myfunc() called.")
11
12     @lockhelper(mylocker)
13     @lockhelper(lockerex)
14     def myfunc2(self, a, b):
15         print(" myfunc2() called.")
16         return a + b
17
18 if __name__=="__main__":
19     a = example()
20     a.myfunc()
21     print(a.myfunc())
22     print(a.myfunc2(1, 2))
23     print(a.myfunc2(3, 4))

下面是参考资料,当初有不少地方没看明白,真正练习后才明白些:

1. Python装饰器学习 http://blog.csdn.net/thy38/article/details/4471421

2. Python装饰器与面向切面编程 http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html

3. Python装饰器的理解 http://apps.hi.baidu.com/share/detail/17572338

时间: 2024-10-06 01:19:20

【转】九步学习python装饰器的相关文章

学习Python装饰器,看这一篇文章就够了

讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切. 谈装饰器前,还要先要明白一件事,Python 中的函数和 Java.C++不太一样,Python 中的函数可以像普通变量一样当做参数传递给另外一个函数,例如: 先来看一个简单例子,虽然实际代码可能比这复杂很多: 说到这里.顺便提醒下大家不管你是为了Python就业还是兴趣爱好,记住:项目开发经验永远是核心,如果你缺新项目练习或者没有python精讲教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的

遥想大肠包小肠----python装饰器乱弹

说起装饰器就tm蛋疼,在老男孩学习python装饰器,结果第二天默写,全错了,一道题抄十遍,共计二十遍. 要是装饰器是一人,我非要约他在必图拳馆来一场...... 下面容我展示一下默写二十遍的成果 语法形式 def  mydec(wenwa): def inner(*args,**kwagrs): ret = wenwa(*args,**kwargs) return ret  #请务必别忘记这还有个该死的return,如果被执行的函数没有返回值return,则ret为None return in

理解Python装饰器(一)

python装饰器 装饰器是什么?我也不知道该如何给装饰器下定义. 1. 装饰器是函数,因为从代码的层面上来说,它就是开发人员定义的一个函数而已: 2. 装饰器就像是类的继承一样,通过装饰符,来实现函数与函数.函数与类之间的"继承" 3. 装饰器是种特殊的语法,通过 `@函数名` 或者 `@类名` 来实现函数或类的继承,但是 装饰器不是继承,装饰器装饰的函数会被当做参数传递给装饰器,这个功能又好像 C++中的虚函数,装饰器装饰的函数用来修改装饰器本身的功能来实现额外功能的添加. 示例:

Python装饰器学习(九步入门)

这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 7 8 # -*- coding:gbk -*- '''示例1: 最简单的函数,表示调用了两次''' def myfunc():     print("myfunc() called.") myfunc() myfunc() 第二步:使用装饰函数在函数执行前和执行后分别附加额外功能 ? 1 2 3 4 5 6 7 8 9 10 11 12 13

[转载]Python装饰器学习(九步入门)

本文转载于: http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 第一步:最简单的函数,准备附加额外功能 # -*- coding:gbk -*- '''示例1: 最简单的函数,表示调用了两次''' def myfunc(): print("myfunc() called.") myfunc() myfunc() 第二步:使用装饰函数在函数执行前和执行后分别附加额外功能 # -*- coding:gbk -*- ''

Python入门之装饰器九步学习入门

第一步:最简单的函数,准备附加额外功能 '''示例1: 最简单的函数,表示调用了两次''' def myfunc(): print("myfunc() called.") myfunc() myfunc() 第二步:使用装饰函数在函数执行前和执行后分别附加额外功能 '''示例2: 替换函数(装饰) 装饰函数的参数是被装饰的函数对象,返回原函数对象 装饰的实质语句: myfunc = deco(myfunc)''' def deco(func): print("before m

Python装饰器学习

Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 7 8 # -*- coding:gbk -*- '''示例1: 最简单的函数,表示调用了两次''' def myfunc():     print("myfunc() called.") myfunc() myfunc() 第二步:使用装饰函数在函数执行前和执行后分别附加额外功能 ? 1 2 3 4 5 6

12步轻松搞定python装饰器

12步轻松搞定python装饰器 呵呵!作为一名教python的老师,我发现学生们基本上一开始很难搞定python的装饰器,也许因为装饰器确实很难懂.搞定装饰器需要你了解一些函数式编程的概念,当然还有理解在python中定义和调用函数相关语法的一些特点. 我没法让装饰器变得简单,但是通过一步步的剖析,我也许能够让你在理解装饰器的时候更自信一点.因为装饰器很复杂,这篇文章将会很长(自己都说很长,还敢这么多废话blablabla...前戏就不继续翻译直接省略了) 1. 函数 在python中,函数通

深入浅出 Python 装饰器:16 步轻松搞定 Python 装饰器

Python的装饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西.虽然好像,他们要干的事都很相似--都是想要对一个已有的模块做一些"修饰工作",所谓修饰工作就是想给现有的模块加上一些小装饰(一些小功能,这些小功能可能好多模块都会用到),但又不让这个小装饰(小功能)侵入到原有的模块中的代码里去.但是OO的Decorator简直就是一场恶梦,不信你就去看看wikipedia上的词条