函数和方法装饰漫谈(Function decorator)
2008-07-22 07:29
316 查看
装饰方法的产生:
Python2.2通过增加静态方法和类方法扩展了Python的对象模型。但是当时没有提供一个简化的语法去定义static/class方法,只得在定义好的方法尾部去调用staticmethod()/classmethod()方法达到目的。例如:class C:
def meth (cls):
meth = classmethod(meth) # 使meth方法成为类方法
但是这样会造成一个问题:当一个方法比较长时,很容易忘记尾部的调用。为了简化这个操作一个新的语法被加了进来:方法装饰,以@开头后跟装饰方法名,如@staticmethod/@classmethod,由此产生出decorator方法及decorator模式。现在我们可以这样写:
class C:
@classmethod
def meth (cls):
可以对一个方法应用多个装饰方法:
@A
@B
@C
def f ():
#等价于下面的形式,Python会按照应用次序依次调用装饰方法(最近的先调用)
def f():
f = A(B(C(f)))
装饰方法解析:
每个decorator只是一个方法, 可以是自定义的或者内置的(如内置的@staticmethod/@classmethod)。decorator方法把要装饰的方法作为输入参数,在函数体内可以进行任意的操作(可以想象其中蕴含的威力强大,会有很多应用场景),只要确保最后返回一个可执行的函数即可(可以是原来的输入参数函数, 或者是一个新函数)。decorator的作用对象可以是模块级的方法或者类方法。decorator根据应用时的参数个数不同分为两类:无参数decorator,有参数decorator。下面分别介绍。无参数decorator:
def deco(func):
"""无参数调用decorator声明时必须有一个参数,这个参数将接收要装饰的方法"""
print "Enter decorator" #进行额外操作
func.attr = 'decorated' #对函数进行操作,增加一个函数属性
return func #返回一个可调用对象(此例还是返回作为输入参数的方法)
#返回一个新函数时,新函数可以是一个全局方法或者decorator函数的内嵌函数,
#只要函数的签名和被装饰的函数相同
@deco
def MyFunc(): #应用@deco修饰的方法
print "Enter MyFunc"
MyFunc() #调用被装饰的函数
注意:当使用上述方法定义一个decorator方法时,函数体内的额外操作只在被装饰的函数首次调用时执行,如果要保证额外操作在每次调用被装饰的函数时都执行,需要换成如下的写法:
def deco(func):
def replaceFunc(): #定义一个内嵌函数,此函数包装了被装饰的函数,并提供额外操作的代码
print "Enter decorator" #进行额外操作
return func() #产生对被装饰函数的调用
return replaceFunc #由于返回的是这个新的内嵌函数,所以确保额外操作每次调用得以运行
@deco
def MyFunc(): #应用@deco修饰的方法
print "Enter MyFunc"
MyFunc() #调用被装饰的函数
有参数decorator:
def decoWithArgs(arg):
"""由于有参数的decorator函数在调用时只会使用应用时的参数而不接收被装饰的函数做为参数,
所以必须返回一个decorator函数, 由它对被装饰的函数进行封装处理"""
def newDeco(func): #定义一个新的decorator函数
def replaceFunc(): #在decorator函数里面再定义一个内嵌函数,由它封装具体的操作
print "Enter decorator" #进行额外操作
return func() #对被装饰函数进行调用
return replaceFunc
return newDeco #返回一个新的decorator函数
@decoWithArgs("demo")
def MyFunc(): #应用@decoWithArgs修饰的方法
print "Enter MyFunc"
MyFunc() #调用被装饰的函数
当我们对某个方法应用了装饰方法后, 其实就改变了被装饰函数名称所引用的函数代码块入口点,使其重新指向了由装饰方法所返回的函数入口点。由此我们可以用decorator改变某个原有函数的功能,添加各种操作,或者完全改变原有实现。
相关文章推荐
- Python的函数和方法装饰漫谈(Function decorator)
- python通过装饰器检查函数参数数据类型的方法
- python函数与方法装饰器
- python通过装饰器检查函数参数数据类型的方法
- string类的两种实现方法及string的一些成员函数的实现
- PHP中CURL方法curl_setopt()函数的参数
- QTCreater编程错误:LNK2019: 无法解析的外部符号 __imp__ShellExecuteW@24,该符号在函数 _main 中被引用 的 错误处理 及 添加外部库与头文件 的方法
- 总结C++中取成员函数地址的几种方法
- 方法(函数)
- 【转帖】深入浅出Dll(介绍函数导出、类导出、钓子dll、不同语言混合编程方法、插件等的实现方法)
- Math:求函数极限的几种方法
- 调用dll中函数的两种方法
- 基于atoi()与itoa()函数的内部实现方法详解
- Python学习 Day 5 高阶函数 map/reduce filter sorter 返回函数 匿名函数 装饰器 偏函数
- python 装饰器 (多个参数的函数,带参数的装饰器)
- [Android] Android Stuio 在函数前面快速生成说明注释和参数注释的方法
- C/C++时间函数使用方法
- STM32的串口函数_库函数USART_SendData问题和解决方法--硬件复位导致第一个字节丢失
- 关于php中header()、setcookie()、session_start()函数错误的解决方法和解释