首頁  >  文章  >  後端開發  >  python之怎麼實現延遲操作

python之怎麼實現延遲操作

王林
王林轉載
2023-05-16 17:16:122091瀏覽

python實作延遲操作

python 想實作延遲的操作是需要套用time ,然後在使用time的sleep 方法

例如我想寫一個延遲1秒列印一次的動作

import time
for i in range(0, 10):
    time.sleep(1)
    print(i)

Python延遲載入問題

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):
    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)
        #进行赋值操作的时候,看是实例化类,还是对类的实例进行赋值操作。因为下面我们要进行实例化类的操作。
    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)
        #在子类中,你应该重新定义它,你通过它,来实现你想要通过何种方式实例化你的类。
    def _init_object(self):
        pass

先看上面的__setattr__,當我們執行user.age=28的賦值操作的時候,就會呼叫該運算符,如果該延遲類別中並沒有實例化我們要引入的類,就會先進行實例化,即呼叫self._init_object,並賦值給_wrapper。如果已經實例化完成,那麼該實例的__setattr__方法就會立即執行。

同理,__getattr_也是一個道理,我想print user.name ,首先要檢查引用的類別是否已經實例化,如果沒有實例化就先實例化,然後再呼叫該實例的__getattr__ 。

好,再看一個實作實例化的子類別: 

class CommonLazyObject(LazyObject):
    def __init__(self,func):
        self.__dict__['_wrapperfunc'] = func
        super(CommonLazyObject,self).__init__()
    def _init_object(self):
        self._wrapper = self._wrapperfunc()

這個子類別實例化的過程很簡單,就直接呼叫了。

以上是python之怎麼實現延遲操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除