python中的装饰器、装饰器模式_装饰器模式在python中的应用

装饰器模式:允许向一个现有的对象添加新的功能,同时又不改变其结构。在python中,装饰器可以是一个函数或者一个类。

在解释装饰器模式时,先理解下python中@符号的含义:

1、@符号是python中的一种修饰符,用来修饰函数,修饰符必须出现在函数定义的前一行,不允许和函数定义在同一行。

2、一个修饰符就是一个函数,它将修饰的函数作为参数,并返回修饰后的同名函数或者其他可以调用的类型。

书面解释比较抽象,来看一个例子:

import time

def get_current_time(func):

print time.time()

return func()

@get_current_time

def sum():

print "sum 函数求和"

运行结果:

1531305351.73

sum 函数求和

其中@符号修饰了sum函数,相当于将sum函数作为参数传入了get_current_time函数,然后执行了get_current_time函数的主体流程。

python中装饰器模式应用分为:

1、函数装饰器,可以理解为装饰器为某个定义的函数。

2、带参数的装饰器,可以理解为装饰器函数可以包含参数传递。

3、类装饰器,可以理解为装饰器为一个定义的类,这种情况一般应用较少。

python内置装饰器有@staticmathod、@classmethod、@property,分别对应静态方法,类方法,类属性。

先看函数装饰器:

import logging

def get_logging(func):

def wrapper(*args, **kwargs):

logging.warn("this is debug log :%s"% func.__name__)

return func(*args, **kwargs)

return wrapper

@get_logging

def test_func():

print "this is a test function"

if __name__ == '__main__':

test_func()

输出结果为:

this is a test function

WARNING:root:this is debug log :test_func

函数get_logging就是装饰器,它将执行真正业务函数test_func包裹在函数中,看起来test_func被get_logging装饰了。简单解释下*args和**kwargs,*args作为函数参数时,是一种可变参数,可以传一个或者多个值,如果定义函数test(*args),那么调用test时,test(1,2,3,None,5),此时的args获取到的值为一个元组tuple,为(1,2,3,None,5);同理**args作为函数参数时,也是一种可变参数,区别是这里传递的值是以键值对呈现的,如果定义函数test(**args),那么调用test时,test(a = 1,b = 2,c = 3),此时的args获取到的值为一个字典dict,值为{'a':1,'b':2,'c':3}。

带参数的装饰器:

装饰器还有更大的宁活性,比如带参数的装饰器。装饰器的语法允许我们在调用时,提供其他参数,比如get_logging(flag),这样就为装饰器的执行提供了更大的灵活性。

比如将上面的例子稍微修改下:

import logging

def use_decorator(level):

def get_logging(func):

def wrapper(*args, **kwargs):

if level == "warn":

logging.warn("this is warn log :%s"% func.__name__)

if level == "error":

logging.error("this is error log :%s" % func.__name__)

return func(*args, **kwargs)

return wrapper

return get_logging

@use_decorator(level = "error")

def test_func():

print "this is a test function"

if __name__ == '__main__':

test_func()

输出结果为:

ERROR:root:this is error log :test_func

this is a test function

给原来的get_logging外层加了一个use_decorator函数,实现函数参数的传递与判断。use_decorator是一个允许带参数的装饰器,实际是对原有装饰器的一个函数封装,并返回一个装饰器。

类装饰器:

相比如函数装饰器,类装饰器具有灵活度大、高内聚、封装性等优点,使用类装饰器还可以依靠内部的__call__方法,当使用@形式将装饰器附加到函数上时,就会调用此方法。

比如下面的例子:

class use_decorator(object):

def __init__(self, func):

self.func = func

def __call__(self, *args, **kwargs):

print "start execute decorator "

self.func()

print "end execute decorator "

@use_decorator

def test_func():

print "this is a test function"

if __name__ == '__main__':

test_func()

执行结果为:

start execute decorator

this is a test function

end execute decorator

相比于第一种函数装饰器,类装饰器是将原始方法传递到初始化__init__函数中,然后调用默认的__call__方法去完成装饰器的执行逻辑。

最后我们看看多层装饰器的嵌套使用,例子如下:

def decorator_A(func):

print "decorator A is call"

return func

def decorator_B(func):

print "decorator B is call"

return func

def decorator_C(func):

print "decorator C is call"

return func

@decorator_A

@decorator_B

@decorator_C

def test_func():

print "this is a test function"

if __name__ == '__main__':

test_func()

执行结果为:

decorator C is call

decorator B is call

decorator A is call

this is a test function

从结果分析,先是执行了最里层装饰器函数decorator_C,然后将传入的方法test_func返回给了外层装饰器decorator_B,同样执行完decorator_B后将被装饰的方法作为参数传递给了装饰器decorator_A,最终完成被装饰器函数test_func的执行。整个过程相当于执行了:decorator_A(decorator_B(decorator_C(test_func)))。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值