国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

無所不能的Python竟然沒有一個(gè)像樣的定時(shí)器?試試這個(gè)!

開發(fā) 后端
所謂定時(shí)器,是指間隔特定時(shí)間執(zhí)行特定任務(wù)的機(jī)制。幾乎所有的編程語言,都有定時(shí)器的實(shí)現(xiàn)。比如,Java有util.Timer和util.TimerTask,JavaScript有setInterval和setTimeout,可以實(shí)現(xiàn)非常復(fù)雜的定時(shí)任務(wù)處理。

[[414409]]

本文轉(zhuǎn)載自微信公眾號(hào)「Python作業(yè)輔導(dǎo)員」,作者天元浪子。轉(zhuǎn)載本文請(qǐng)聯(lián)系Python作業(yè)輔導(dǎo)員公眾號(hào)。

所謂定時(shí)器,是指間隔特定時(shí)間執(zhí)行特定任務(wù)的機(jī)制。幾乎所有的編程語言,都有定時(shí)器的實(shí)現(xiàn)。比如,Java有util.Timer和util.TimerTask,JavaScript有setInterval和setTimeout,可以實(shí)現(xiàn)非常復(fù)雜的定時(shí)任務(wù)處理。然而,牛叉到無所不能的Python,卻沒有一個(gè)像樣的定時(shí)器,實(shí)在令人難以理解。

剛?cè)腴T的同學(xué)一定會(huì)說:不是有個(gè)time.sleep嗎?定好鬧鐘睡大覺,鬧鐘一響,起來干活,這不就是一個(gè)定時(shí)器嗎?沒錯(cuò),time.sleep具備定時(shí)器的基本要素,但若作為定時(shí)器使用,則有兩個(gè)致命的缺陷:一是阻塞主線程,睡覺的時(shí)候不能做任何事情;二是醒來以后需要主線程執(zhí)行定時(shí)任務(wù)——即便使用線程技術(shù),也得先由主線程來創(chuàng)建子線程。

說到這里,熟悉線程模塊threading的同學(xué)也許會(huì)說:threading.Timer就是以線程方式運(yùn)行的呀,既不會(huì)阻塞主線程,執(zhí)行定時(shí)任務(wù)也無需主線程干預(yù),這不就是一個(gè)完美的定時(shí)器嗎?

我們先來看看threading.Timer是如何工作的。下面這段代碼演示了threading.Timer的基本用法:啟動(dòng)定時(shí)器2秒鐘后以線程方式調(diào)用函數(shù)do_something,在定時(shí)器等待的2秒鐘內(nèi),以及do_something運(yùn)行期間,主線程仍然可以做其他工作——此處是從鍵盤讀取輸入,借以阻塞主線程,以便觀察定時(shí)器的工作情況。

  1. import time 
  2. import threading 
  3.  
  4. def do_something(name, gender='male'): 
  5.     print(time.time(), '定時(shí)時(shí)間到,執(zhí)行特定任務(wù)' ) 
  6.     print('name:%s, gender:%s'%(name, gender)) 
  7.  
  8. timer = threading.Timer(2, do_something, args=('Alice',), kwargs={'gender':'female'}) 
  9. timer.start() 
  10. print(time.time(), '定時(shí)開始時(shí)間'
  11. input('按回車鍵結(jié)束\n') # 此處阻塞主進(jìn)程 

正如我們所期待的那樣,定時(shí)器啟動(dòng)2秒鐘后,函數(shù)do_something被調(diào)用,這期間可以隨時(shí)敲擊回車鍵結(jié)束程序。這段代碼的運(yùn)行結(jié)果如下。

  1. 1627438957.4297626 定時(shí)開始時(shí)間 
  2. 按回車鍵結(jié)束 
  3. 1627438959.4299397 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  4. name:Alice, gender:female 

從使用效果看,threading.Timer稱得上是一款簡潔易用的定時(shí)器。不過,threading.Timer存在明顯的短板,那就是不支持連續(xù)的定時(shí)任務(wù),比如,每隔2秒鐘調(diào)用一次do_something函數(shù)。如果一定要用threading.Timer實(shí)現(xiàn)連續(xù)定時(shí),只能用類似嵌套的變通方法,在do_something函數(shù)中再次啟動(dòng)定時(shí)器。

  1. import time 
  2. import threading 
  3.  
  4. def do_something(name, gender='male'): 
  5.     global timer 
  6.     timer = threading.Timer(2, do_something, args=(name,), kwargs={'gender':gender}) 
  7.     timer.start() 
  8.  
  9.     print(time.time(), '定時(shí)時(shí)間到,執(zhí)行特定任務(wù)' ) 
  10.     print('name:%s, gender:%s'%(name, gender)) 
  11.     time.sleep(5) 
  12.     print(time.time(), '完成特定任務(wù)' ) 
  13.  
  14. timer = threading.Timer(2, do_something, args=('Alice',), kwargs={'gender':'female'}) 
  15. timer.start() 
  16. input('按回車鍵結(jié)束\n') # 此處阻塞主進(jìn)程 

這段代碼重新定義了do_something函數(shù),在函數(shù)開始位置啟動(dòng)下一次的定時(shí)任務(wù)。之所以放在開始位置,是為了保證兩次定時(shí)之間的時(shí)間間隔盡可能精確。饒是如此,下面的運(yùn)行結(jié)果顯示,兩次定時(shí)之間的時(shí)間間隔比設(shè)計(jì)的2秒鐘多了大約10毫秒,且誤差是連續(xù)累計(jì)的,重復(fù)執(zhí)行100次,誤差將會(huì)超過1秒鐘。

  1. 按回車鍵結(jié)束 
  2. 1627440628.683803 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  3. name:Alice, gender:female 
  4. 1627440630.6929214 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  5. name:Alice, gender:female 
  6. 1627440632.707388 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  7. name:Alice, gender:female 
  8. 1627440633.6890671 完成特定任務(wù) 
  9. 1627440634.722474 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  10. name:Alice, gender:female 
  11. 1627440635.7092102 完成特定任務(wù) 
  12. 1627440636.7277966 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  13. name:Alice, gender:female 

針對(duì)連續(xù)的定時(shí)任務(wù),threading.Timer的表現(xiàn)還算差強(qiáng)人意,只是這種嵌套的寫法完全顛覆了代碼美學(xué)。對(duì)于像我這樣有代碼潔癖的程序員來說,是無法容忍和不可接受的。在我看來,一個(gè)完美的定時(shí)器應(yīng)該滿足以下5個(gè)條件,具備下圖所示的結(jié)構(gòu)。

  1. 不阻塞主線程
  2. 同時(shí)支持單次定時(shí)和連續(xù)定時(shí)
  3. 以線程或進(jìn)程方式執(zhí)行定時(shí)任務(wù)
  4. 定時(shí)任務(wù)的線程或進(jìn)程的創(chuàng)建、運(yùn)行,不影響定時(shí)精度
  5. 足夠精確的定時(shí)精度,且誤差不會(huì)累計(jì)

既然Python沒有提供一個(gè)像樣的定時(shí)器,那就自己寫一個(gè)吧。下面這個(gè)定時(shí)器,滿足上面提到的5個(gè)條件,最短時(shí)間間隔可以低至10毫秒,且誤差不會(huì)累計(jì)。雖然還不夠完美,但無論結(jié)構(gòu)還是精度,都還說得過去。

  1. import time 
  2. import threading 
  3.  
  4. class PyTimer: 
  5.     """定時(shí)器類""" 
  6.  
  7.     def __init__(self, func, *args, **kwargs): 
  8.         """構(gòu)造函數(shù)""" 
  9.  
  10.         self.func = func 
  11.         self.args = args 
  12.         self.kwargs = kwargs 
  13.         self.running = False 
  14.  
  15.     def _run_func(self): 
  16.         """運(yùn)行定時(shí)事件函數(shù)""" 
  17.  
  18.         th = threading.Thread(target=self.func, args=self.args, kwargs=self.kwargs) 
  19.         th.setDaemon(True
  20.         th.start() 
  21.  
  22.     def _start(self, interval, once): 
  23.         """啟動(dòng)定時(shí)器的線程函數(shù)""" 
  24.  
  25.         if interval < 0.010: 
  26.             interval = 0.010 
  27.  
  28.         if interval < 0.050: 
  29.             dt = interval/10 
  30.         else
  31.             dt = 0.005 
  32.  
  33.         if once: 
  34.             deadline = time.time() + interval 
  35.             while time.time() < deadline: 
  36.                 time.sleep(dt) 
  37.  
  38.             # 定時(shí)時(shí)間到,調(diào)用定時(shí)事件函數(shù) 
  39.             self._run_func() 
  40.         else
  41.             self.running = True 
  42.             deadline = time.time() + interval 
  43.             while self.running: 
  44.                 while time.time() < deadline: 
  45.                     time.sleep(dt) 
  46.  
  47.                 # 更新下一次定時(shí)時(shí)間 
  48.                 deadline += interval 
  49.  
  50.                 # 定時(shí)時(shí)間到,調(diào)用定時(shí)事件函數(shù) 
  51.                 if self.running: 
  52.                     self._run_func() 
  53.  
  54.     def start(self, interval, once=False): 
  55.         """啟動(dòng)定時(shí)器 
  56.  
  57.         interval    - 定時(shí)間隔,浮點(diǎn)型,以秒為單位,最高精度10毫秒 
  58.         once        - 是否僅啟動(dòng)一次,默認(rèn)是連續(xù)的 
  59.         ""
  60.  
  61.         th = threading.Thread(target=self._start, args=(interval, once)) 
  62.         th.setDaemon(True
  63.         th.start() 
  64.  
  65.     def stop(self): 
  66.         """停止定時(shí)器""" 
  67.  
  68.         self.running = False 

定時(shí)器類PyTimer實(shí)例化時(shí),需要傳入定時(shí)任務(wù)函數(shù)。如果定時(shí)任務(wù)函數(shù)有參數(shù),也可以按照位置參數(shù)、關(guān)鍵字參數(shù)的順序一并提供。PyTimer定時(shí)器提供start和stop兩個(gè)方法,用于啟動(dòng)和停止定時(shí)器。其中stop方法不需要參數(shù),start則需要一個(gè)以秒為單位的定時(shí)間隔參數(shù)。start還有一個(gè)布爾型的默認(rèn)參數(shù)once,可以設(shè)置是否單次定時(shí)。once參數(shù)的默認(rèn)值為False,即默認(rèn)連續(xù)定時(shí);如果需要單次定時(shí),只需要將once置為true即可。

  1. def do_something(name, gender='male'): 
  2.     print(time.time(), '定時(shí)時(shí)間到,執(zhí)行特定任務(wù)' ) 
  3.     print('name:%s, gender:%s'%(name, gender)) 
  4.     time.sleep(5) 
  5.     print(time.time(), '完成特定任務(wù)' ) 
  6.  
  7. timer = PyTimer(do_something, 'Alice', gender='female'
  8. timer.start(0.5, once=False
  9.  
  10. input('按回車鍵結(jié)束\n') # 此處阻塞主進(jìn)程 
  11. timer.stop() 

上面是使用PyTimer定時(shí)器以0.5秒鐘的間隔連續(xù)調(diào)用函數(shù)do_something的例子。這段代碼的運(yùn)行結(jié)果如下。

  1. 按回車鍵結(jié)束 
  2. 1627450313.425347 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  3. name:Alice, gender:female 
  4. 1627450313.9226055 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  5. name:Alice, gender:female 
  6. 1627450314.421761 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  7. name:Alice, gender:female 
  8. 1627450314.9243422 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  9. name:Alice, gender:female 
  10. 1627450315.422722 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  11. name:Alice, gender:female 
  12. 1627450315.9200313 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  13. name:Alice, gender:female 
  14. 1627450316.4204514 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  15. name:Alice, gender:female 
  16. 1627450316.9215539 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  17. name:Alice, gender:female 
  18. 1627450317.4228196 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  19. name:Alice, gender:female 
  20. 1627450317.9245899 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  21. name:Alice, gender:female 
  22. 1627450318.42355 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  23. name:Alice, gender:female 
  24. 1627450318.4393418 完成特定任務(wù) 
  25. 1627450318.9251466 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  26. name:Alice, gender:female 
  27. 1627450318.9395308 完成特定任務(wù) 
  28. 1627450319.4242043 完成特定任務(wù) 
  29. 1627450319.4242043 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  30. name:Alice, gender:female 
  31. 1627450319.9253905 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  32. name:Alice, gender:female 
  33. 1627450319.9411068 完成特定任務(wù) 
  34. 1627450320.425871 完成特定任務(wù) 
  35. 1627450320.425871 定時(shí)時(shí)間到,執(zhí)行特定任務(wù) 
  36. name:Alice, gender:female 
雖然每個(gè)定時(shí)任務(wù)需要運(yùn)行5秒鐘,但每隔0.5秒都會(huì)準(zhǔn)時(shí)啟動(dòng)一個(gè)新的線程運(yùn)行定時(shí)任務(wù)。從記錄可以看出,盡管每次定時(shí)任務(wù)的啟動(dòng)時(shí)間有幾個(gè)毫秒的誤差,但誤差不會(huì)累計(jì),重復(fù)執(zhí)行的時(shí)間間隔均值始終穩(wěn)定在0.5秒。
 
【責(zé)任編輯:武曉燕 TEL:(010)68476606】

 

責(zé)任編輯:武曉燕 來源: Python作業(yè)輔導(dǎo)員
相關(guān)推薦

2021-04-07 10:02:18

人工智能技術(shù)互聯(lián)網(wǎng)

2013-05-22 14:05:18

2009-07-06 18:43:13

VB指針

2021-04-17 23:05:29

手機(jī)黑科技APP

2023-11-28 12:09:43

Linux網(wǎng)絡(luò)工具

2025-02-17 00:00:25

CSS工具樣式

2015-04-30 14:53:43

Build 2015微軟Azure

2021-04-20 10:47:59

手機(jī)APP科技

2024-06-14 09:21:56

2021-08-16 10:13:26

AI DeepMind人工智能

2014-06-13 02:21:14

2021-04-05 22:37:29

微信小程序手機(jī)

2021-04-01 13:07:07

編碼開發(fā)代碼

2015-10-28 15:47:22

谷歌物聯(lián)網(wǎng)互聯(lián)網(wǎng)

2014-03-11 23:02:00

2009-11-11 10:14:10

linux定時(shí)器操作系統(tǒng)

2010-07-28 15:56:22

FlexTimer定時(shí)

2011-09-12 15:32:58

2022-11-02 11:40:16

Flowable定時(shí)器流程

2022-09-26 08:26:38

軟件定時(shí)器函數(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

久久久精品国产亚洲| 国产精品九九久久久久久久| 亚洲视频自拍偷拍| 欧美视频日韩| 特级全黄一级毛片| 国产成人精品电影久久久| 不卡精品视频| 成人资源www网在线最新版| 综合久久给合久久狠狠狠97色| 国产精品欧美激情| 日韩一区二区三区四区五区 | 亚洲a一区二区三区| 六月婷婷久久| 国产精品99免费看| 国产激情视频网址| 国产精品电影久久久久电影网| 久久久久久久久久美女| 在线日韩网站| 黄页免费在线观看视频| www国产精品com| 亚洲品质自拍视频网站| 欧美成人一区在线观看| 97久久人人超碰caoprom欧美 | 99re66热这里只有精品8| 久草在线中文888| 精品无码久久久久久久动漫| 色欧美88888久久久久久影院| 欧美日韩国内| 国际av在线| 久久国产精品久久| 日韩欧美在线视频免费观看| 久久成人在线| 精品视频在线观看网站| 久久久久久久久久伊人| 色狠狠久久aa北条麻妃| 国产精品欧美综合在线| 色女人在线视频| 精品日韩欧美在线| 中文在线免费二区三区| 一区二区三区国产视频| 性刺激综合网| 亚洲精品资源| 国产一区精品福利| 久久这里只有精品8| 欧美日韩在线视频观看| 性爽视频在线| av毛片免费| 国产精品7m视频| 中文字幕在线免费不卡| 中文在线资源| 欧美一区二区三区在线免费观看| 97国产suv精品一区二区62| 成人的网站免费观看| 在线观看麻豆| caoporn视频在线观看| 中文字幕亚洲无线码a| 国产欧美欧洲| 国产亚洲视频在线观看| 久久精品久久久| 日本中文字幕电影在线观看| 国产一区二区香蕉| 日韩一区欧美一区| 99国产成+人+综合+亚洲欧美| 羞羞污视频在线观看| 在线无限看免费粉色视频| 亚洲欧美日韩综合| 日本一区二区三区在线不卡| 亚洲经典在线| 小h片在线观看| www.九色在线| 清纯唯美一区二区三区| 国产小视频在线观看| 97中文字幕| 91深夜福利视频| 亚洲社区在线观看| 亚洲国产欧美在线| 久久久久高清精品| 久久在线精品| 中文字幕亚洲无线码在线一区| 久久sese| 三上悠亚在线观看二区| 国产福利久久精品| 日韩精品视频三区| 久久精品亚洲精品国产欧美 | 91麻豆精品国产自产在线| 国产精品小仙女| 亚洲精品国产首次亮相| 日韩在线综合| 亚洲福利影视| 手机在线看福利| 欧美福利视频在线观看| 欧美一区二区免费观在线| 日本大胆人体视频| 日本高清不卡在线| 欧美精品一区二区精品网| gogo在线高清视频| 精品久久一二三| 91久久精品www人人做人人爽 | 2018高清国产日本一道国产| www99xav| av手机在线观看| 精品久久影视| 国产成人午夜视频| 午夜精品久久久久影视| 亚洲图片欧美午夜| 成人午夜在线视频一区| 欧美在线观看www| 男人天堂久久久| 久久精品免费播放| 亚洲国产精久久久久久| 精品国精品自拍自在线| 久久久国产在线视频| 亚洲91精品在线观看| 欧美精品亚洲| 99视频日韩| 久久丝袜美腿综合| 欧美三级午夜理伦三级富婆| 亚洲综合电影| 人成在线免费网站| 久久99精品久久只有精品| 亚洲综合影院| 亚洲成a人v欧美综合天堂麻豆| 日产精品久久久久久久蜜臀| 国产成人免费av电影| 亚洲跨种族黑人xxx| 亚洲成人免费在线观看| 免费不卡在线观看| 久久av导航| 国产嫩草在线视频| 黄页网站在线观看| 亚洲精品福利视频网站| 亚洲精品网站在线播放gif| 国产.精品.日韩.另类.中文.在线.播放| 成人免费视频网站在线观看| 不卡一区二区在线| 欧美精品在线视频| 这里只有精品在线| 人人精品久久| av在线免费观看网站| 少妇激情一区二区三区| 日韩免费毛片| 国产在线拍偷自揄拍精品| 精品国产依人香蕉在线精品| 91精品中文字幕一区二区三区| 国产精品麻豆视频| 国产精品123| 亚洲一区国产| 欧美3p视频| 国产精品一区二区精品| 污污视频在线看| 手机福利小视频在线播放| 天天碰免费视频| 亚洲国产精品影视| 99re视频在线观看| 国产精品扒开腿做爽爽爽视频| xxxxx91麻豆| 日韩精品福利网站| 91麻豆精品国产91| 一本久道久久综合中文字幕| 亚洲女与黑人做爰| 久久久精品影视| 成人一区二区三区视频在线观看 | 国产精品v日韩精品v在线观看| 一本—道久久a久久精品蜜桃| 91在线播放视频| 国产精品电影网站| 欧美大片网站在线观看| 国产一区二区三区网站| 欧美不卡一二三| 欧美日韩dvd在线观看| 国产精品日本一区二区不卡视频 | 91精品啪在线观看国产18| 91精品啪在线观看国产爱臀| 成人国产激情| 电影网一区二区| 97天天综合网| 伊人222成人综合网| 成人动漫在线免费观看| 污视频在线看操| 一个人免费视频www在线观看| 3dmax动漫人物在线看| 91免费日韩| eeuss鲁片一区| 黄色一级视频网站| 一级网站免费观看| 亚洲第一区视频| 久久国产精品高清一区二区三区| 中文字幕在线视频观看| 亚洲永久精品免费| 最猛黑人系列在线播放| 一级二级在线观看| 极品美乳网红视频免费在线观看| 日韩亚洲视频在线观看| 成人性生交大片免费看午夜| 视频免费一区| 99久久精品免费观看国产| 91吃瓜在线观看| 99精品在免费线偷拍| 国产美女福利在线观看| 欧美一区二区三区电影|