python裡面的延遲載入用得非常多,其主要思想是延遲所要引入類的例項化,節省一些初始化所需要的時間和空間。這種思想在django中應用得也是非常廣泛,比如orm的queryset,還有鑑權中介軟體中的request.user等等,這些都是利用了延遲載入的思想。
本文就是通過例子來分析延遲載入的思想。
實現延遲載入的基本思路是我建立乙個類,我們將我們需要例項化的類傳給他,這時該類都會變成乙個延遲載入類,在應用的時候,雖然我例項化了這個延遲載入類,但是我們要引用的類就沒有例項化。就像下面這樣:
class user(object):
def __init__(self):
self.name = 'haibo'
self.age = 23
def test():
return user()
#初始化該延遲載入類
user = commonlazyobject(lambda :test())
#此時我們要引用的類才執行
user.age = 28
上面我定義了乙個user類,它是我們在程式中要引用的類,commonlazyobject是我們定義的延遲載入類(後面再說)。通過延遲載入類,我們不必要提前初始化它,只有我們想進行如下面的user.age的操作的時候,才會進行例項化。
好,下面看一下延遲載入類的具體實現過程。
思想:我們對於乙個例項化的操作,無非最終會歸結為__getattr__,__setattr__等運算子,因此只要我們定義好這些運算子就可以實現這些延遲,即只有執行這些操作的時候,才去真正例項化我們想要例項化的類:
#建立乙個空的物件
empty = object()
#乙個裝飾器,對__getattr__進行裝飾,使得其可以進行類的例項化
def proxy_getattr(func):
self._init_object()
class lazyobject(object):
def __init__(self):
__getattr__ = proxy_getattr(getattr)
#進行賦值操作的時候,看是例項化類,還是對類的例項進行賦值操作。因為下面我們要進行例項化類的操作。
def __setattr__(self, key, value):
else:
self._init_object()
#在子類中,你應該重新定義它,你通過它,來實現你想要通過何種方式例項化你的類。
def _init_object(self):
pass
同理,__getattr_也是乙個道理,我想print user.name ,首先要檢查引用的類是否已經例項化,如果沒有例項化就先例項化,然後再呼叫該例項的__getattr__。
好,再看乙個實現例項化的子類:
class commonlazyobject(lazyobject):這個子類例項化的過程很簡單,就直接呼叫了。def __init__(self,func):
super(commonlazyobject,self).__init__()
def _init_object(self):
ok!上面就介紹了延遲載入的思想以及建立過程。可能,我說的是最基本的實現方法,但也是django中經常用的。
懶載入 延遲載入
概念 為了推遲和資料庫互動的時間,推遲到真正需要這個物件資料的時候。提高系統的效能 通過 asm和cglib二個jar包實現懶載入。domain是非final的 1 session.load懶載入 1 返回的是乙個 物件,new關鍵字來建立乙個 物件,理解成乙個快捷方式,不是真正的類,而是 類。2 ...
python中的懶惰載入問題(延遲載入)
python中的懶惰載入用途非常多,可以節省記憶體,其主要的思想就是延遲載入需要例項化的類。python是通過getattr和setattr實現的,和使用方法如下。class lazy object def init self,lazy object,args,kwargs self.dict ar...
python 生成器 延遲載入
進入python shell x 1,2,3 y i 2 for i in x y 2,4,6 type y 這樣得到的y是list型別 y i 2 for i in x y at 0xb74ee89c type y 將中括號用圓括號去替代後,y變成生成器物件,延遲載入了,只是宣告出表示式而沒有做真...