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

目录
相关文章
|
16天前
|
监控 Python
Python中的装饰器:提升代码灵活性与可读性
在Python编程中,装饰器是一种强大的工具,能够提升代码的灵活性和可读性。本文将介绍装饰器的基本概念、使用方法以及实际应用场景,帮助读者更好地理解和利用这一功能。
|
18天前
|
缓存 监控 Python
解密Python中的装饰器:优雅而强大的编程利器
Python中的装饰器是一种强大而又优雅的编程工具,它能够在不改变原有代码结构的情况下,为函数或类添加新的功能和行为。本文将深入解析Python装饰器的原理、用法和实际应用,帮助读者更好地理解和利用这一技术,提升代码的可维护性和可扩展性。
|
1月前
|
缓存 算法 测试技术
Python中的装饰器:原理与实践
【2月更文挑战第29天】 在Python编程领域,装饰器是一种强大的工具,它允许我们在不修改原始函数代码的情况下,增加或修改函数的行为。本文将深入探讨Python装饰器的概念、实现原理以及实际应用,帮助读者掌握这一技术并在实际项目中灵活运用。
|
2天前
|
存储 缓存 Python
Python装饰器
Python装饰器
12 0
|
3天前
|
Python
深入理解Python中的装饰器
在Python编程中,装饰器(decorators)是一种强大的工具,用于增强函数或类的功能而不改变其原始定义。本文将深入探讨装饰器的概念、用法和实际应用,帮助读者更好地理解和利用这一特性。
|
3天前
|
数据安全/隐私保护 Python
Python中的装饰器:提升代码可读性和灵活性
Python中的装饰器是一种强大的编程工具,能够提升代码的可读性和灵活性。本文将深入探讨装饰器的原理和用法,以及如何利用装饰器来简化代码、实现日志记录、权限控制等功能,从而让你的Python代码更加优雅和高效。
|
9天前
|
数据安全/隐私保护 Python
Python中的装饰器:提升代码可读性与灵活性
Python中的装饰器是一种强大的工具,可以在不改变函数原有逻辑的情况下,为函数添加额外的功能。本文将介绍装饰器的基本概念和用法,并通过实例演示如何利用装饰器提升代码的可读性和灵活性,使代码更加简洁、易于维护。
|
9天前
|
缓存 大数据 数据处理
Python迭代器、生成器和装饰器探究
【4月更文挑战第2天】 迭代器是遍历集合元素的对象,实现`__iter__()`和`__next__()`方法。示例中自定义迭代器`MyIterator`用于生成整数序列。 - 生成器简化了迭代器实现,利用`yield`关键词实现状态保存,减少内存占用。示例中的`my_generator`函数即为一个生成器。 - 装饰器用于修改函数行为,如日志记录、性能分析。装饰器`my_decorator`在函数调用前后添加额外代码。
23 0
|
11天前
|
程序员 Python
Python中的装饰器:提升代码可读性与灵活性
在Python编程中,装饰器是一种强大的工具,可以在不修改原始代码的情况下,动态地添加功能。本文将深入探讨Python中装饰器的原理、用法和实际应用,以及如何利用装饰器提升代码的可读性和灵活性。
|
13天前
|
缓存 开发者 Python
深入探讨Python中的装饰器:提升代码可读性与灵活性
在Python编程中,装饰器是一种强大的工具,可以在不修改原始函数代码的情况下,对其行为进行扩展或修改。本文将深入探讨装饰器的原理和用法,以及如何利用装饰器提升代码的可读性和灵活性,为Python开发者提供更加优雅和高效的编程方式。