python 装饰器

来源:互联网 发布:易哲软件 编辑:程序博客网 时间:2024/06/11 16:31

装饰器是设计模式的一种,在面向对象中可以实现动态的给对象添加功能,通常使用对象组合的方式来实现。

如现在有个类A有个操作operation定义如下:

class A:    def operation(self):        print 'sonme operation'

我们需要对A的操作进行装饰,希望在operation前后做一些装饰操作,所以我们实现如下装饰类:

class Decrator:    def __init__(self, obj):        self.obj = obj    def operation(self):        print 'do something before operation'        self.obj.operation()        print 'do something after operation'

python中的装饰器类似上面功能,目的是在不影响原有实现的基础上,在调用原来实现之前或者之后增加一层逻辑,比如说鉴权、缓存、超时设置、统计监控等。

装饰器也是函数,它可以用来装饰其它函数,所以是一个嵌套函数的结构。

def outter(a):    def inner(b):        return a + b    return innero = outter(112)print o(23)
以下是最简单的一个python装饰器的实现:

def decorator(fn):    fn.cnt = 0    def warpper(x):        fn.cnt += 1        print fn.cnt        return fn(x)    return warpper @decoratordef action(x):      return x*x   action(3)action(3)  action(3)
以上输出为:

1

2

3
装饰器函数默认参数为被装饰的函数,在代码被加载时就执行

如上,加载装饰器后action对应的定义已经改变,类似于:

raw_action = action
action = decorator(raw_action)

以上的装饰器函数装饰时没有传递参数,默认参数就是被装饰函数,但有时候我们也需要对装饰函数传递一些参数,如缓存的时间

def cache(timeout):    def decorator(func):        def wrapper(*args):            if timeout > 10:                return func(*args)            else:                print 'get value from cache'                return 'cache value'        return wrapper    return decorator@cache(10)def test(x, y):    return x*ytest(12, 12)

以上输出为:

get value from cache

由于有参数的装饰函数在调用时只会使用应用时的参数 而不接收被装饰的函数做为参数,所以必须在其内部再创建一个函数用来接收被装饰函数作为参数

这时的test定义类似于:

raw_test = testtest = cache(10)(raw_test)

当然,装饰器也可以组合使用,多个装饰器来装饰一个函数

def decorator(fn):    fn.cnt = 0    def wrapper(x):        fn.cnt += 1        print fn.cnt        return fn(x)    return wrapperdef decorator2(fn):    def wrapper(*args):        print 'another decorator2'        return fn(*args)    return wrapper @decorator@decorator2def action(x):      return x*x
装饰的顺序为由近及远,即离被装饰函数最近的装饰器开始自底向上执行装饰

raw_action = actionaction = decorator2(raw_action)action = decorator(action)



0 0
原创粉丝点击