django 中的延遲加載技術,python中的lazy技術

---恢復內容開始---數據庫

提及lazy_object,首先想到的是django orm中的query_set、fn.Stream這兩個類。django

query_set只在須要數據庫中的數據的時候才 產生db hits。Stream對象只有在用到index時纔會去一次次next。app

例子:
   f = Stream ()
         fib = f << [ 0 , 1 ] << iters . map ( add , f , iters . drop ( 1 , f ))

 1行生成了斐波那契數列。ide

說明:函數

  f是個lazy的對象,f首先放入了0和1,而後放入了迭代器iters.map。等f[2]的時候。就會調用1次next(iters.map(add, f, iters.drop(1, f))),在map的迭代器中,next(f)和next(drop(1,f))被放到add兩端。ui

很高端大氣上檔次有木有!lua

這裏有個django的lazy的實現代碼,spa

 對象的code

#coding: utf-8
#
class LazyProxy(object):

    def __init__(self, cls, *args, **kwargs):

        self.__dict__['_cls'] = cls
        self.__dict__['_params'] = args
        self.__dict__['_kwargs'] = kwargs

        self.__dict__["_obj"]=None

    def __getattr__(self, item):

        if self.__dict__['_obj'] is None:
            self._init_obj()

        return getattr(self.__dict__['_obj'], item)


    def __setattr__(self, key, value):

        if self.__dict__['_obj'] is None:
            self._init_obj()

        setattr(self.__dict__['_obj'], key , value)


    def _init_obj(self):

        self.__dict__['_obj']=object.__new__(self.__dict__['_cls'],
                                             *self.__dict__['_params'],
                                             **self.__dict__['_kwargs'])
        self.__dict__['_obj'].__init__(*self.__dict__['_params'],
                                       **self.__dict__['_kwargs'])


class LazyInit(object):

    def __new__(cls, *args, **kwargs):
        return LazyProxy(cls, *args, **kwargs)


class A(LazyInit):

    def __init__(self, x):

        print ("Init A")
        self.x = 14 + x


a = A(1)
print "Go"
print a.x

原理:在類的__new__方法中hook一下,使其返回lazy_proxy 的對象。而後調用__init__方法時,其實就是調用proxy的__init__方法,第一次調用時orm

也就是當A生成實例時,Proxy纔會真正產生一個A的類,並初始化這個類,注意,在這裏proxy的init中獲得的cls是A而不是Lazy_Init,由於只有A(1)調用時A的__new__纔會調用,雖然__new__名字的查找在LazyInit中。


函數的lazy:

""" 
lazy - Decorators and utilities for lazy evaluation in Python 
Alberto Bertogli (albertito@blitiri.com.ar) 
"""  
  
class _LazyWrapper:  
    """Lazy wrapper class for the decorator defined below. 
    It's closely related so don't use it. 
 
    We don't use a new-style class, otherwise we would have to implement 
    stub methods for __getattribute__, __hash__ and lots of others that 
    are inherited from object by default. This works too and is simple. 
    I'll deal with them when they become mandatory. 
    """  
    def __init__(self, f, args, kwargs):  
        self._override = True  
        self._isset = False  
        self._value = None  
        self._func = f  
        self._args = args  
        self._kwargs = kwargs  
        self._override = False  
  
    def _checkset(self):  
        print '111111111111', self._isset, self._value  
        if not self._isset:  
            self._override = True  
            self._value = self._func(*self._args, **self._kwargs)  
            self._isset = True  
            self._checkset = lambda: True  
            self._override = False  
  
    def __getattr__(self, name):  
        print '----------getattr----',  name  
        if self.__dict__['_override']:  
            return self.__dict__[name]  
        self._checkset()  
        print '@@@@@@@@@', self._value, type(self._value), name, self._value.__getattribute__(name)  
        return self._value.__getattribute__(name)  
  
    def __setattr__(self, name, val):  
        print '----------setattr----',  name, val  
        if name == '_override' or self._override:  
            self.__dict__[name] = val  
            return  
        self._checkset()  
        print '222222222222222'  
        setattr(self._value, name, val)  
        return  
  
def lazy(f):  
    "Lazy evaluation decorator"  
    def newf(*args, **kwargs):  
        return _LazyWrapper(f, args, kwargs)  
  
    return newf  
 
 
@lazy  
def quick_exe():  
    print '---------quick exe-----------'  
    return 'quickquick'  
  
import pdb  
#pdb.set_trace()  
  
quick_exe()  
print '#####################'  
print quick_exe()

 

 

---恢復內容結束---

相關文章
相關標籤/搜索