python之如何實(shí)現(xiàn)延遲操作
python實(shí)現(xiàn)延遲操作
python 想實(shí)現(xiàn)延遲的操作是需要應(yīng)用time ,然后在使用time的sleep 方法
比如我想寫(xiě)一個(gè)延遲1秒打印一次的操作
import time
for i in range(0, 10):
time.sleep(1)
print(i)Python延遲加載問(wèn)題
Python里面的延遲加載用得非常多,其主要思想是延遲所要引入類(lèi)的實(shí)例化,節(jié)省一些初始化所需要的時(shí)間和空間。
這種思想在Django中應(yīng)用得也是非常廣泛,比如ORM的QuerySet,還有鑒權(quán)中間件中的request.user等等,這些都是利用了延遲加載的思想。
本文就是通過(guò)例子來(lái)分析延遲加載的思想。
實(shí)現(xiàn)延遲加載的基本思路是我創(chuàng)建一個(gè)類(lèi),我們將我們需要實(shí)例化的類(lèi)傳給他,這時(shí)該類(lèi)都會(huì)變成一個(gè)延遲加載類(lèi),在應(yīng)用的時(shí)候,雖然我實(shí)例化了這個(gè)延遲加載類(lèi),但是我們要引用的類(lèi)就沒(méi)有實(shí)例化。
就像下面這樣:
class User(object): ?? ?def __init__(self): ?? ??? ?self.name = 'haibo' ?? ??? ?self.age = 23 def test(): ?? ?return User() #初始化該延遲加載類(lèi) user = CommonLazyObject(lambda :test()) #此時(shí)我們要引用的類(lèi)才執(zhí)行 user.age = 28
上面我定義了一個(gè)User類(lèi),它是我們?cè)诔绦蛑幸玫念?lèi),CommonLazyObject是我們定義的延遲加載類(lèi)(后面再說(shuō))。通過(guò)延遲加載類(lèi),我們不必要提前初始化它,只有我們想進(jìn)行如下面的user.age的操作的時(shí)候,才會(huì)進(jìn)行實(shí)例化。
好,下面看一下延遲加載類(lèi)的具體實(shí)現(xiàn)過(guò)程。
思想:我們對(duì)于一個(gè)實(shí)例化的操作,無(wú)非最終會(huì)歸結(jié)為_(kāi)_getattr__,__setattr__等運(yùn)算符,因此只要我們定義好這些運(yùn)算符就可以實(shí)現(xiàn)這些延遲,即只有執(zhí)行這些操作的時(shí)候,才去真正實(shí)例化我們想要實(shí)例化的類(lèi):
#建立一個(gè)空的對(duì)象 empty = object() #一個(gè)裝飾器,對(duì)__getattr__進(jìn)行裝飾,使得其可以進(jìn)行類(lèi)的實(shí)例化 def proxy_getattr(func): ?? ?def wrapper(self,*args): ?? ??? ?if self._wrapper is empty: ?? ??? ??? ?self._init_object() ?? ??? ?return func(self._wrapper,*args) ?? ?return wrapper class LazyObject(object): ?? ?def __init__(self): ?? ??? ?self._wrapper = empty ?? ?__getattr__ = proxy_getattr(getattr) ? ? ? ? #進(jìn)行賦值操作的時(shí)候,看是實(shí)例化類(lèi),還是對(duì)類(lèi)的實(shí)例進(jìn)行賦值操作。因?yàn)橄旅嫖覀円M(jìn)行實(shí)例化類(lèi)的操作。 ?? ?def __setattr__(self, key, value): ?? ??? ?if key == '_wrapper': ?? ??? ??? ?self.__dict__['_wrapper'] = value ?? ??? ?else: ?? ??? ??? ?if self._wrapper is empty: ?? ??? ??? ??? ?self._init_object() ?? ??? ??? ?setattr(self._wrapper,key,value) ? ? ? ? #在子類(lèi)中,你應(yīng)該重新定義它,你通過(guò)它,來(lái)實(shí)現(xiàn)你想要通過(guò)何種方式實(shí)例化你的類(lèi)。 ?? ?def _init_object(self): ?? ??? ?pass
先看上面的__setattr__,當(dāng)我們執(zhí)行user.age=28的賦值操作的時(shí)候,就會(huì)調(diào)用該運(yùn)算符,如果該延遲類(lèi)中并沒(méi)有實(shí)例化我們要引入的類(lèi),就會(huì)先進(jìn)行實(shí)例化,即調(diào)用self._init_object,并賦值給_wrapper。如果已經(jīng)實(shí)例化好了,就會(huì)直接進(jìn)行這個(gè)實(shí)例的__setattr__。
同理,__getattr_也是一個(gè)道理,我想print user.name ,首先要檢查引用的類(lèi)是否已經(jīng)實(shí)例化,如果沒(méi)有實(shí)例化就先實(shí)例化,然后再調(diào)用該實(shí)例的__getattr__。
好,再看一個(gè)實(shí)現(xiàn)實(shí)例化的子類(lèi):
class CommonLazyObject(LazyObject): ?? ?def __init__(self,func): ?? ??? ?self.__dict__['_wrapperfunc'] = func ?? ??? ?super(CommonLazyObject,self).__init__() ?? ?def _init_object(self): ?? ??? ?self._wrapper = self._wrapperfunc()
這個(gè)子類(lèi)實(shí)例化的過(guò)程很簡(jiǎn)單,就直接調(diào)用了。
OK!上面就介紹了延遲加載的思想以及創(chuàng)建過(guò)程??赡?,我說(shuō)的是最基本的實(shí)現(xiàn)方法,但也是Django中經(jīng)常用的。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python中的jquery PyQuery庫(kù)使用小結(jié)
這篇文章主要介紹了Python中的jquery PyQuery庫(kù)使用小結(jié),需要的朋友可以參考下2014-05-05
Python3實(shí)現(xiàn)發(fā)送郵件和發(fā)送短信驗(yàn)證碼功能
這篇文章主要介紹了Python3實(shí)現(xiàn)發(fā)送郵件和發(fā)送短信驗(yàn)證碼功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
Python實(shí)現(xiàn)圖形用戶界面計(jì)算器
這篇文章主要為大家詳細(xì)介紹了Python實(shí)現(xiàn)圖形用戶界面計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
Python和JS反爬之解決反爬參數(shù)?signKey
這篇文章主要介紹了Python和JS反爬之解決反爬參數(shù)?signKey,Python?反爬中有一大類(lèi),叫做字體反爬,核心的理論就是通過(guò)字體文件或者?CSS?偏移,接下來(lái)文章的詳細(xì)介紹,需要的小伙伴可以參考一下2022-05-05
Python flask框架定時(shí)任務(wù)apscheduler應(yīng)用介紹
Flask是Python社區(qū)非常流行的一個(gè)Web開(kāi)發(fā)框架,本文將嘗試將介紹APScheduler應(yīng)用于Flask之中實(shí)現(xiàn)定時(shí)任務(wù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-10-10
10個(gè)Python實(shí)現(xiàn)的最頻繁使用的聚類(lèi)算法
聚類(lèi)或聚類(lèi)分析是無(wú)監(jiān)督學(xué)習(xí)問(wèn)題。它通常被用作數(shù)據(jù)分析技術(shù),用于發(fā)現(xiàn)數(shù)據(jù)中的有趣模式。本文為大家介紹了10個(gè)最頻繁使用的聚類(lèi)算法,感興趣的可以了解一下2022-12-12
設(shè)計(jì)模式中的原型模式在Python程序中的應(yīng)用示例
這篇文章主要介紹了設(shè)計(jì)模式中的原型模式在Python程序中的應(yīng)用示例,文中主要強(qiáng)調(diào)了對(duì)淺拷貝和深拷貝在對(duì)象復(fù)制時(shí)的使用,需要的朋友可以參考下2016-03-03
python如何用pymodbus庫(kù)進(jìn)行modbus tcp通信
這篇文章主要介紹了python如何用pymodbus庫(kù)進(jìn)行modbus tcp通信問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
pycharm-professional-2020.1下載與激活的教程
這篇文章主要介紹了pycharm-professional-2020.1下載與激活的教程,本文分為安裝和永久激活兩部分內(nèi)容,需要的朋友可以參考下2020-09-09
OPENAI?API?微調(diào)?GPT-3?的?Ada?模型
這篇文章主要為大家介紹了OPENAI?API?微調(diào)?GPT-3?的?Ada?模型使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04

