国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

python從寫循環(huán)定時(shí)器學(xué)習(xí)Timer

lemon / 2078人閱讀

摘要:更循環(huán)定時(shí)器這里有更的方法重點(diǎn)研究類,它繼承了,但是重寫了父類的方法。再看看類中的語句,直到才會(huì)退出循環(huán),定時(shí)器才結(jié)束。我們知道定時(shí)器有一個(gè)方法可以提前取消操作。這樣便完成了一個(gè)還不錯(cuò)的循環(huán)定時(shí)器。

python 如何寫一個(gè)定時(shí)器,循環(huán)定時(shí)做某一操作呢?

Timer 對(duì)象
from threading import Timer
def hello(): 
    print "hello, world" 
   
t = Timer(10.0, hello) 
t.start()

10秒后輸出:

hello, world

重點(diǎn)研究 t = Timer(10.0, hello) 這句代碼,python 提供了一個(gè)Timer 對(duì)象,它會(huì)在指定的時(shí)間后執(zhí)行某一操作;它的完整形式:

class threading.Timer(interval, function, args=[], kwargs={})

interval 是時(shí)間間隔,function 是可調(diào)用的對(duì)象,argskwargs 會(huì)作為 function 的參數(shù)。

注意:這里只會(huì)執(zhí)行一次 function,而不會(huì)一直定時(shí)執(zhí)行,且 Timer 在執(zhí)行操作的時(shí)候會(huì)創(chuàng)建一個(gè)新的線程。

Timer 在 python2 和 python3 有點(diǎn)區(qū)別:

# python2.7
def Timer(*args, **kwargs):
    return _Timer(*args, **kwargs)
# python3.7
class Timer(Thread):
    pass

在 python3,TimerThread 的子類;在 python2,_TimerThread 的子類,而 Timer 只是 _Timer 類的工廠方法。

上面的代碼只會(huì)打印一次 hello, world 后退出,那么如何循環(huán)間隔打印呢?

粗陋的循環(huán)定時(shí)器

一種方法是在 function 里繼續(xù)注冊(cè)一個(gè) Timer,這樣就可以在下一個(gè) interval 繼續(xù)執(zhí)行 function

from threading import Timer
def hello(): 
    print "hello, world" 
    Timer(10.0, hello) .start()

t = Timer(10.0, hello) 
t.start()

每隔 10 秒輸出一個(gè) hello, world

達(dá)到效果了,但是這里面好像有點(diǎn)問題。回到 Timer 本身,它是一個(gè) thread,每次循環(huán)間隔操作,系統(tǒng)都要?jiǎng)?chuàng)建一個(gè)線程,然后再回收,這對(duì)系統(tǒng)來說開銷很大。如果時(shí)間間隔 interval 很短,系統(tǒng)會(huì)一下子創(chuàng)建很多線程,這些線程很難快速回收,導(dǎo)致系統(tǒng)內(nèi)存和cpu資源被消耗掉。
所以不提倡在 function 里繼續(xù)注冊(cè)一個(gè) Timer。

更 pythonic 循環(huán)定時(shí)器

這里有更 pythonic 的方法:

from threading import _Timer
def hello():
     print "hello, world"
class RepeatingTimer(_Timer): 
    def run(self):
        while not self.finished.is_set():
            self.function(*self.args, **self.kwargs)
            self.finished.wait(self.interval)
t = RepeatingTimer(10.0, hello)
t.start()

重點(diǎn)研究 RepeatingTimer 類,它繼承了 threading._Timer,但是重寫了父類的 run 方法。這是 Python2 的寫法,python3 中 RepeatingTimer 應(yīng)該繼承 threading.Timer

為什么要重寫 Threadrun 方法?

_Timer 是一個(gè) Thread 子類,我們先看看 Thread 類的 run 用法。

from threading import Thread
def hello():
     print "hello, world"
# 繼承 Thread
class MyThread(Thread):
    # 把要執(zhí)行的代碼寫到run函數(shù)里面 線程在創(chuàng)建后會(huì)直接運(yùn)行run函數(shù)
    def run(self):
        hello()
t = MyThread()
t.start()

Thread 對(duì)象的完整定義:

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})

其中 run 方法代碼:

class Thread(_Verbose):
    def run(self):
        try:
            if self.__target:
                self.__target(*self.__args, **self.__kwargs)
        finally:
            # Avoid a refcycle if the thread is running a function with
            # an argument that has a member that points to the thread.
            del self.__target, self.__args, self.__kwargs

標(biāo)準(zhǔn)的 run 方法用于執(zhí)行用戶傳入構(gòu)造函數(shù)的 target 方法。 子類可以重寫 run 方法,把要執(zhí)行的代碼寫到 run 里面,線程在創(chuàng)建后,用戶調(diào)用 start() 方法會(huì)運(yùn)行 run() 方法。

所以 RepeatingTimer 重寫 _Timer 的 run() 方法,可以改變線程的執(zhí)行體,當(dāng)我們調(diào)用 RepeatingTimer 的 start() 方法時(shí)會(huì)執(zhí)行我們重寫的 run() 方法。

再看看 RepeatingTimer 類中的 while not self.finished.is_set() 語句,self.finished.is_set() 直到 True 才會(huì)退出循環(huán),定時(shí)器才結(jié)束。finishedthreading.Event 對(duì)象。一個(gè) Event 對(duì)象管理著一個(gè) flag 標(biāo)志,它能被 set() 方法設(shè)置為 True,也能被 clear() 方法設(shè)置為 False,調(diào)用 wait([timeout]) 線程會(huì)一直 sleep 到 flag 為 True 或超時(shí)時(shí)間到達(dá)。

我們知道定時(shí)器有一個(gè) cancel() 方法可以提前取消操作。它其實(shí)是調(diào)用 Event.clear() 方法提前讓 wait 方法結(jié)束等待,并且判斷在 flag 為 true 的情況下不執(zhí)行定時(shí)器操作。具體的代碼:

class _Timer(Thread):
    """Call a function after a specified number of seconds:
            t = Timer(30.0, f, args=[], kwargs={})
            t.start()
            t.cancel() # stop the timer"s action if it"s still waiting
    """

    def __init__(self, interval, function, args=[], kwargs={}):
        Thread.__init__(self)
        self.interval = interval
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.finished = Event()

    def cancel(self):
        """Stop the timer if it hasn"t finished yet"""
        self.finished.set()

    def run(self):
        self.finished.wait(self.interval)
        if not self.finished.is_set():
            self.function(*self.args, **self.kwargs)
        self.finished.set()

所以 RepeatingTimer 的 run 方法會(huì)一直執(zhí)行 while 循環(huán)體,在循環(huán)體了會(huì)執(zhí)行用戶傳入的 function 對(duì)象,并等待指定的時(shí)間。當(dāng)用戶想退出定時(shí)器時(shí),只需要調(diào)用 cancel 方法,將 flag 置為 True 便不會(huì)繼續(xù)執(zhí)行循環(huán)體了。這樣便完成了一個(gè)還不錯(cuò)的循環(huán)定時(shí)器。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/43373.html

相關(guān)文章

  • Python算法引入

    摘要:參數(shù)是要測(cè)試的代碼語句參數(shù)是運(yùn)行代碼時(shí)需要的設(shè)置參數(shù)是一個(gè)定時(shí)器函數(shù),與平臺(tái)有關(guān)。類中測(cè)試語句執(zhí)行速度的對(duì)象方法。參數(shù)是測(cè)試代碼時(shí)的測(cè)試次數(shù),默認(rèn)為次。方法返回執(zhí)行代碼的平均耗時(shí),一個(gè)類型的秒數(shù)。 [TOC] 這里主要是算法的介紹以及一些判斷算法好壞的標(biāo)準(zhǔn)和方式 引入 如果a+b+c = 1000,且a^2 + b^2 = c^2,如何求出所有a,b,c可能的組合? 第一次嘗試: im...

    Godtoy 評(píng)論0 收藏0
  • Python中的上下文管理器和else塊

    摘要:上下文管理器協(xié)議包含和兩個(gè)方法。因此必要時(shí)在上下文管理器函數(shù)中使用語句防范錯(cuò)誤。構(gòu)建臨時(shí)忽略指定異常的上下文管理器。這是個(gè)基類,用于定義基于類的上下文管理器。塊結(jié)束時(shí),按照后進(jìn)先出的順序調(diào)用棧中各個(gè)上下文管理器的方法。 導(dǎo)語:本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之控制流程篇的重點(diǎn)知識(shí)及個(gè)人心得,打算入門Python的朋友們可以來一起學(xué)習(xí)并交流。 本文重點(diǎn): 1、掌握if語句之外的el...

    Michael_Lin 評(píng)論0 收藏0
  • 瀏覽器和Node中的事件循環(huán)機(jī)制

    摘要:二瀏覽器端在講解事件循環(huán)之前先談?wù)勚型酱a異步代碼的執(zhí)行流程。三端我自己認(rèn)為的事件循環(huán)和瀏覽器端還是有點(diǎn)區(qū)別的,它的事件循環(huán)依靠引擎。四總結(jié)本篇主要介紹了瀏覽器和對(duì)于事件循環(huán)機(jī)制實(shí)現(xiàn),由于能力水平有限,其中可能有誤之處歡迎指出。 一、前言 前幾天聽公司一個(gè)公司三年的前端說今天又學(xué)到了一個(gè)知識(shí)點(diǎn)-微任務(wù)、宏任務(wù),我問他這是什么東西,由于在吃飯他淺淺的說了下,當(dāng)時(shí)沒太理解就私下學(xué)習(xí)整理一...

    KevinYan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<