Python延遲載入

2021-08-21 03:06:53 字數 1660 閱讀 8261

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變成生成器物件,延遲載入了,只是宣告出表示式而沒有做真...