码迷,mamicode.com
首页 > 其他好文 > 详细

装饰器类学习小结

时间:2018-07-06 16:40:17      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:com   types   类型   pre   ref   key   例子   follow   参数   

装饰器

装饰器的原理以及函数类型的装饰器在网上有很多描述,本文我就只讲我对于 将装饰器定义为类的理解。

要将装饰器定义为一个类,需要在类中声明__call____get__方法,例子如下:

from time import time

class ttl_property(object):
    def __init__(self, ttl=None):
       self.ttl = ttl

    def __call__(self, func):
       def wrapper(*args,**kw):
          if ‘name‘ not in self.__dict__.keys():
             self.__dict__[‘name‘]=(func(*args,**kw),time())
          last=self.__dict__[‘name‘][1]
          value=self.__dict__[‘name‘][0]
          now=time()
          if now-last>self.ttl:
             value=func(*args,**kw)
             self.__dict__[‘name‘]=(value,now)
          return value
       return wrapper

    def __get__(self, instance, owner):
       if instance is None:
            return self
       else:
            return types.MethodType(self, instance)

    def __set__(self, instance, value):
       self.__dict__[‘name‘] = (value, time())
from ttl_property import ttl_property

class Book(object):
    """
    >>> b = Book()
    >>> b.price
    80.0
    >>> b.price
    80.0
    >>> time.sleep(3)
    >>> b.price
    64.0
    >>> b.price
    64.0
    >>> time.sleep(3)
    >>> b.price
    51.2
    """

    def __init__(self):
        self._price = 100.0

    @ttl_property(ttl=2)
    def price(self):
        self._price = self._price * 0.8
        return self._price

这是我在一个网站上做的实验,在这个实验中需要定义一个装饰器类ttl_property来装饰Book类中的函数,__call__函数可以将类的调用和函数类似,具体请查询网上资料。

我要着重强调两点:

1:装饰器类中的__get__方法很重要,因为在装饰器中返回的函数并不是原本类中的函数,也就是说在原本类所对应的实例中,这个函数并不存在,所以如果没有__get__方法,那么调用就会出问题;那么types.MethodType(self, instance)就是将方法和实例绑定起来,这样在这个实例中就包含了这个方法,就可以顺利调用了。

2:如果在原来的方法中需要使用self,那么在装饰器返回的方法中也要包含self参数,不然就不行

装饰器类学习小结

标签:com   types   类型   pre   ref   key   例子   follow   参数   

原文地址:http://blog.51cto.com/zhengdzy/2137203

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!