python装饰器的使用

简介: http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 这是在Python学习小组上介绍的内容,现学现卖、多练习是好的学习方式。

http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

这是在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
14
15
16
17
18
# -*- coding:gbk -*-
'''示例2: 替换函数(装饰)
装饰函数的参数是被装饰的函数对象,返回原函数对象
装饰的实质语句: myfunc = deco(myfunc)'''
 
def  deco(func):
     print ( "before myfunc() called." )
     func()
     print ( "  after myfunc() called." )
     return  func
 
def  myfunc():
     print ( " myfunc() called." )
 
myfunc  =  deco(myfunc)
 
myfunc()
myfunc()

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding:gbk -*-
'''示例5: 对带参数的函数进行装饰,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
 
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  +  b
 
myfunc( 1 2 )
myfunc( 3 4 )

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# -*- coding:gbk -*-
'''示例6: 对参数数量不确定的函数进行装饰,
参数用(*args, **kwargs),自动适应变参和命名参数'''
 
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 )
myfunc( 3 4 )
myfunc2( 1 2 3 )
myfunc2( 3 4 5 )

第七步:让装饰器带参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# -*- coding:gbk -*-
'''示例7: 在示例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()

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# -*- coding:gbk -*-
'''示例8: 装饰器带类参数'''
 
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文件中,同时演示了对一个函数应用多个装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# -*- coding:gbk -*-
'''mylocker.py: 公共类 for 示例9.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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- 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  +  b
 
if  __name__ = = "__main__" :
     =  example()
     a.myfunc()
     print (a.myfunc())
     print (a.myfunc2( 1 2 ))
     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

目录
相关文章
|
21天前
|
开发者 Python
探索Python中的装饰器:从基础到高级应用
本文将带你深入了解Python中的装饰器,这一强大而灵活的工具。我们将一起探讨装饰器的基本概念,它们如何工作,以及如何使用它们来增强函数和类的功能,同时不改变其核心逻辑。通过具体代码示例,我们将展示装饰器的创建和使用,并探索一些高级应用,比如装饰器堆栈和装饰带参数的装饰器。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角,帮助你更有效地使用装饰器来简化和优化你的代码。
|
22天前
|
测试技术 数据安全/隐私保护 开发者
探索Python中的装饰器:从基础到高级应用
装饰器在Python中是一个强大且令人兴奋的功能,它允许开发者在不修改原有函数代码的前提下增加额外的功能。本文将通过具体代码示例,带领读者从装饰器的基础概念入手,逐步深入到高级用法,如带参数的装饰器和装饰器嵌套等。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
22天前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
31 6
|
10天前
|
缓存 数据安全/隐私保护 Python
python装饰器底层原理
Python装饰器是一个强大的工具,可以在不修改原始函数代码的情况下,动态地增加功能。理解装饰器的底层原理,包括函数是对象、闭包和高阶函数,可以帮助我们更好地使用和编写装饰器。无论是用于日志记录、权限验证还是缓存,装饰器都可以显著提高代码的可维护性和复用性。
23 5
|
24天前
|
测试技术 Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界中,装饰器是那些能够为我们的代码增添魔力的小精灵。它们不仅让代码看起来更加优雅,还能在不改变原有函数定义的情况下,增加额外的功能。本文将通过生动的例子和易于理解的语言,带你领略装饰器的奥秘,从基础概念到实际应用,一起开启Python装饰器的奇妙旅程。
35 11
|
21天前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
装饰器,在Python中是一块强大的语法糖,它允许我们在不修改原函数代码的情况下增加额外的功能。本文将通过简单易懂的语言和实例,带你一步步了解装饰器的基本概念、使用方法以及如何自定义装饰器。我们还将探讨装饰器在实战中的应用,让你能够在实际编程中灵活运用这一技术。
37 7
|
20天前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
21天前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
44 6
|
20天前
|
存储 缓存 Python
Python中的装饰器深度解析与实践
在Python的世界里,装饰器如同一位神秘的魔法师,它拥有改变函数行为的能力。本文将揭开装饰器的神秘面纱,通过直观的代码示例,引导你理解其工作原理,并掌握如何在实际项目中灵活运用这一强大的工具。从基础到进阶,我们将一起探索装饰器的魅力所在。
|
21天前
|
测试技术 开发者 Python
深入理解Python装饰器:从基础到高级应用
本文旨在为读者提供一个全面的Python装饰器指南,从其基本概念讲起,逐步深入探讨其高级应用。我们将通过实例解析装饰器的工作原理,并展示如何利用它们来增强函数功能、控制程序流程以及实现代码的模块化。无论你是Python初学者还是经验丰富的开发者,本文都将为你提供宝贵的见解和实用的技巧,帮助你更好地掌握这一强大的语言特性。
32 4