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 ([email protected])
"""

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()

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

django 中的延迟加载技术,python中的lazy技术,码迷,mamicode.com

时间: 2024-08-06 20:07:11

django 中的延迟加载技术,python中的lazy技术的相关文章

Python中什么是变量Python中定义字符串

在Python中,变量的概念基本上和初中代数的方程变量是一致的. 例如,对于方程式 y=x*x ,x就是变量.当x=2时,计算结果是4,当x=5时,计算结果是25. 只是在计算机程序中,变量不仅可以是数字,还可以是任意数据类型. 在Python程序中,变量是用一个变量名表示,变量名必须是大小写英文.数字和下划线(_)的组合,且不能用数字开头 例如 : 在Python中,等号=是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,例如:  这种变量本身类型不固

钉钉扫码登录中的签名算法在python中的实现

签名算法为HmacSHA256,签名数据是当前时间戳timestamp,密钥是appId对应的appSecret计算出来的签名值,算出来的digest再经过base64加密后即是所需要的签名数据.官方文档中只给了Java和PHP的示例demo,因此,根据Java和PHP的demo写一个python版的. 1 import hmac 2 from base64 import standard_b64encode 3 4 5 def get_ding_talk_signature(app_secre

numpy中int类型与python中的int

[code] import numpy as np nparr = np.array([[1 ,2, 3, 4]]) np_int32 = nparr[0][0] # np_int=1 py_int = 1234 #打印类型 print("type(py_int32)="+str(type(py_int32))) print("type(np_int)="+str(type(np_int))) #numpy 的int32 转 int64 np_int64=np.in

python中_、__和__xx__的区别

python中_.__和__xx__的区别 本文为译文,版权属于原作者,在此翻译为中文分享给大家. 英文原文地址:Difference between _, __ and __xx__ in Python 在学习Python时,很多人都弄不清楚各种下划线的意思,而且在这之前已经给其他人解释过很多遍了,是时候把它记录下来. "_"单下划线 Python中不存在真正的私有方法.为了实现类似于c++中私有方法,可以在类的方法或属性前加一个“_”单下划线,意味着该方法或属性不应该去调用,它并不

zhlan--【偷】Python中的赋值运算符

>>>>Python中的赋值运算符: >>>>Python中的比较运算符:

(转载)Python中:self和__init__的含义 +

(注:原文地址 Python中:self和__init__的含义 + 为何要有self和__init__) 背景 回复: 我写的一些Python教程,需要的可以看看 中SongShouJiong的提问: Python中的self,__init__的含义是啥? 为何要有self,__init这些东西? 解释之前,先说几句 1.到目前为止,我虽然也已写了不算很少的python的代码,但是,还真的没有太多接触self和__init__这两个东西. 只能算是大概了解. 2.为了搞懂其含义,现学现卖,去看

Python中,添加写入数据到已经存在的Excel的xls文件,即打开excel文件,写入新数据

背景 Python中,想要打开已经存在的excel的xls文件,然后在最后新的一行的数据. 折腾过程 1.找到了参考资料: writing to existing workbook using xlwt 其实是没有直接实现: 打开已有的excel文件,然后在文件最后写入,添加新数据 的函数的. 只不过,可以利用: Working with Excel Files in Python 中的库,组合实现. 2. writing to existing workbook using xlwt 给出了示

python中对象初始化放在内存中什么位置

截屏自<Python源码剖析>正文第一页. 也即: 当在其他class中使用 时,node是在堆中的.相当于在C中调用malloc. 不仅仅是对于像Node这样的class 的对象是存在于堆中的,在Python中就连int类型的数值同样是存在在堆中的.因为在Python中就连基本数据类型同样是对象. 让我们思考下Node中的value和self.value这两个变量: 为什么在Node中其他的方法能够调用self.value而不能够调用value? 以前我使用C/C++的思维方法来理解这个问题

关于python中的面向对象

对于面向对象(oop)的理解 在人类的认知中,我们习惯把属性相近的东西进行归类.所以,我们写的class xxx就是一个类,描述了一组属性的集合.而我们把这组属性具体实例出来的称之为对象 比如: class Bird(object):       def __init__(self,feather,call):           self.feather=feather           self.call=call 我们定义了一个鸟的类,并且初始化函数定义了它有羽毛,可以叫.这个就是类 b

浅析python中的类变量和对象变量

刚学python,学到了有关于类和对象的地方.对一个概念有点模糊,后来通过实践编码找到一定规律 在python中 class test(object): id=2 name='tt' list=['tt','dd'] def change(self,newA,new_id): self.id=new_id self.age=newA return self.age t1 = test() t1.change(21, 3) print t1.id #3 t2 = test() t2.age = 2