利用decorator和descriptor進行數據緩存

class cached_property(object):                                                                                                                           

    def __init__(self, func, name=None, doc=None):
        self.__name__ = name or func.__name__
        self.__module__ = func.__module__
        self.__doc__ = doc or func.__doc__
        self.func = func

    def __get__(self, obj, type=None):
        if obj is None:
            return self
        value = obj.__dict__.get(self.__name__, None)
        if value is None:
            value = self.func(obj)
            obj.__dict__[self.__name__] = value
        return value

 

今天在werkzurg上看到上面的代碼,寫得真是精彩!html

 

一般咱們descrator是這麼寫的python

def cached_property(func):
    def _(*args, **kwargs):
            return func(*args, **kwargs)
    return _

 

從代碼形式上看,這是一個函數調用,返回一個函數,在python語法上decorator爲下面的編寫方式:緩存

@cached_property
def func():
      return 42

 

而代碼的執行方式和cached_property(func)是同樣的,這是一種閉包的形式,這種形式和定義一個object,__init__第一個參數是func,以後定義一個__call__是等價的。在werkzurg中採用了前面的方式__init__來獲取和decorator相同的行爲,而__init__返回的是cached_property對象,這個對象使用__get__這個descriptor特性。閉包

 

當調用@cached_property修飾的屬性名稱時,便會調用生成的對象的__get__方法,從而能夠更加仔細的調用func方法獲取具體的值,從而緩存起來!!!函數

 

對descriptor不熟悉的能夠看python文檔:http://docs.python.org/2/howto/descriptor.htmlspa

 

perfect!code

相關文章
相關標籤/搜索