欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

python自定義時鐘類、定時任務類

系統 1642 0

這是我使用python寫的第一個類(也算是學習面向對象語言以來正式寫的第一個解耦的類),記錄下改進的過程。

分析需求

最初,因為使用time模塊顯示日期時,每次都要設置時間字符串的格式,挺麻煩,但還是忍了。
后來,在處理多線程任務時需要實現定時控制的功能,更麻煩,終于決定自己做一個解決這些問題的通用代碼(雖然網上有現成的模塊,但親手編寫這部分代碼正好能鍛煉一下我的面向對象編程)。

分析框架

剛開始,我計劃做一個模仿時鐘的抽象類,讓它獨立運行在一個線程中,讓它提供顯示日期、計時、設置定時任務的方法……然而由于缺乏規劃,編程亂糟糟的,這些方法的代碼和變量交雜在一起,難以入目,更難以擴展……氣得重構代碼,這次把顯示日期、計時、設置定時任務三大功能分別抽象成三個類,相互解耦,各自獨立運行,代碼變得簡潔多了。
ok,舊代碼就藏在git的歷史記錄里吧,這里貼出重構后的代碼。

顯示時間的類

            
import time
import threading


class _Clock:
  """
  自定義的時鐘類,用于獲取幾種不同格式的當前時間。
   decimal : 設置time_float的精度,控制其保留幾位小數。
   time_diff : 設置該時鐘與UTC+0時區的時差。如果不設置,會自動采用
   本地時區。
  """

  def __init__(self, name=None, decimal=3, time_diff=None):
    self.name = name
    self.decimal = decimal
    self.time_diff = time_diff
    self.time_format = "%Y/%m/%d %H:%M:%S" # 時間字符串的格式

  @property
  def time_float(self):
    """ UTC+0時區的時間戳,精度由self.decimal決定 """
    return round(time.time(), self.decimal)

  @property
  def time_int(self):
    """ UTC+0時區的時間戳,精度為秒 """
    return int(time.time())

  @property
  def time_tuple(self):
    """ 本地時區的時間元組 """
    if self.time_diff == None:
      return time.localtime(self.time_int)
    else:
      return time.gmtime(self.time_int+self.time_diff)

  @property
  def time_str(self):
    """ 本地時間的格式化字符串 """
    return time.strftime(self.time_format, self.time_tuple)
          

秒表計時的類

            
class Timer(_Clock):
  """
  自定義的計時器,像秒表一樣,可以隨時查看當前計時、暫停計時、繼續計時。
   ? 創建一個計時器之后,它就會開始計時。
   ? 默認使用time.time()獲取時間,精度為毫秒。
   ? 可以直接調用_Clock類的方法來獲取當前時間。
  """

  def __init__(self, *args, **kwargs):
    _Clock.__init__(self, *args, **kwargs)
    self.record = [] # 記錄每次使用的 (開始時刻,暫停時刻,計時時長)
    self.status = "initial"
    self.go()

  @property
  def count(self):
    """ 當前計時值 """
    count = 0
    for line in self.record:
      if line[2] == None:
        count += self.time_float - line[0]
      else:
        count += line[2]
    return round(count, self.decimal)

  def go(self):
    """ 開始計時 """
    if self.status != "timing":
      self.record.append((self.time_float, None, None))
      self.status = "timing"

  def pause(self):
    """ 暫停計時 """
    # 如果該計時器在計時中,就暫停它,并計算這一段的計時時長
    if self.status == "timing":
      last_line = self.record[-1]
      self.record.remove(last_line)
      current_time = self.time_float
      self.record.append(
        (last_line[0], current_time, round(current_time - last_line[0], self.decimal)))
      self.status = "paused"
          

定時任務的類

            
class Schedule(threading.Thread):
  """
  自定義的定時任務表,添加第一個定時任務后就創建一個線程,開始循環檢查
  是否執行任務表中的任務。
   ? 調用stop()來終止該線程。
  """

  def __init__(self, *args, **kwargs):
    threading.Thread.__init__(self, *args, **kwargs)
    self._askToStop = False
    self._schedule = [] # 保存定時任務表
    self.status = "initial"

  def _get_time(self):
    """ 獲取當前時間 """
    return time.time()

  def addTask(self, countDown, func, *args, **kwargs):
    """ 
    在任務表中增加一項定時任務:在倒計時countDown結束之后調用
    函數func,并傳入參數*args和**kwargs。
     ? 定時任務只會被執行一次,執行后就會被從任務表中刪除。
     ? 定時任務只會在倒計時結束之后被執行,但無法保證無延遲。
    """
    if self.status == "initial": # 第一次添加定時任務時創建一個新線程
      self.status = "running"
      self.start()

    task = []
    if isinstance(countDown, (int, float)) and countDown > 0:
      task.append(self._get_time()+countDown) # 準備在指定時刻執行該任務
    else:
      raise ValueError("'countDown' must be a positive int or float.")
    if callable(func):
      task.append(func)
    else:
      raise ValueError("'func' must be callable.")
    task.append(args) # 保存元組參數
    task.append(kwargs) # 保存字典參數

    self._schedule.append(task)
    self._schedule.sort(key=lambda task: task[0]) # 將任務表按時間戳的大小排序

  def _doTask(self):
    """ 檢查任務表中各項任務的時間,判斷是否要執行它。 """
    current_time = self._get_time()
    i = 0
    while i < len(self._schedule): # 遍歷任務表
      task = self._schedule[i]
      if task[0] <= current_time:
        # 如果該任務的時間不晚于當前時間,就創建一個線程去執行該任務,避免阻塞定時器線程
        t1 = CreatThread(task[1], *task[2], **task[3])
        t1.start()
        i += 1
      else:
        break # 如果該任務的時間戳大于當前時間,就提前結束遍歷

    del self._schedule[:i] # 刪除過時的任務

  def run(self):
    """ 線程循環運行的內容 """
    while not self._askToStop:
      self._doTask()

    # 結束時進行清理
    self.status == "stopped"
    return 0

  def stop(self):
    self._askToStop = True


class CreatThread(threading.Thread):
  """ 一個簡單的創建線程的類 """

  def __init__(self, func, *args, **kwargs):
    threading.Thread.__init__(self)
    self.func = func
    self.args = args
    self.kwargs = kwargs

  def run(self):
    self.func(*self.args, **self.kwargs)
          

源代碼:use_time.py

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 成人精品福利 | 日韩中文字幕不卡 | 色偷偷免费 | 日韩亚洲欧美中文高清在线 | 亚洲欧美另类综合 | 国产亚洲精品久久久久久一区二区 | 日日干干夜夜 | 精品美女在线观看视频在线观看 | 国产成人精品一区二区在线 | 夜精品A片观看无码一区二区 | 欧美日韩亚洲综合另类ac | 高清一区二区三区四区五区 | 国产成人精品一区二区三区视频 | www.国产精| 欧美一级高清免费 | 久草网站 | 午夜视频久久 | av一区在线观看 | 2018一级毛片免费观看 | 国产一区在线播放 | 日韩中文字幕免费在线观看 | 天天操欧美 | 欧美一区二区三区大片 | 成人免费在线视频 | 日韩精品一区二区三区中文字幕 | 亚洲啊v在线观看 | 在线观看国产wwwa级羞羞视频 | 亚洲国产日韩欧美在线 | 日韩精品视频免费在线观看 | 97福利社| 欧美精品一区二区三区在线 | 这里只有精品在线视频观看 | 欧美日韩亚洲视频 | 欧美黑人性受xxxx喷水 | 噜噜色网| 青青草91| 国产成人精品福利网站在线观看 | 老汉色影院 | 久久久精品视频免费观看 | 欧美亚洲第一页 | 成人av在线网 |