zoukankan      html  css  js  c++  java
  • django 中的延迟加载技术,python中的lazy技术

    ---恢复内容开始---

    说起lazy_object,首先想到的是django orm中的query_set、fn.Stream这两个类。

    query_set只在需要数据库中的数据的时候才 产生db hits。Stream对象只有在用到index时才会去一次次next。

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

     1行生成了斐波那契数列。

    说明:

      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两端。

    很高端大气上档次有木有!

    这里有个django的lazy的实现代码,

     对象的

    #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__方法,第一次调用时

    也就是当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()

    ---恢复内容结束---

  • 相关阅读:
    测试工具文件4. 数据分析——定义analyseXML
    关于sprintf的"_CRT_SECURE_NO_WWARNINGS"问题的解决
    测试工具文件3. 输出文件——定义TestLog
    测试工具文件2. 支持代码——定义TestUtility
    测试工具文件1. 平台问题——定义Platform.h
    python之正则表达式
    python之字典总结
    python之global关键字的用法
    python + selenium 常用方法验证页面上的UI元素
    python + selenium 元素定位方法 (索引)By属性
  • 原文地址:https://www.cnblogs.com/Yeah-come-on/p/3697041.html
Copyright © 2011-2022 走看看