<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      翻譯:《實用的Python編程》08_02_Logging

      目錄 | 上一節(jié) (8.1 測試) | 下一節(jié) (8.3 調(diào)試)

      8.2 日志

      本節(jié)對日志模塊(logging module)進(jìn)行簡單的介紹。

      logging 模塊

      logging 模塊是用于記錄診斷信息的 Python 標(biāo)準(zhǔn)庫模塊。日志模塊非常龐大,具有許多復(fù)雜的功能。我們將會展示一個簡單的例子來說明其用處。

      再探異常

      在本節(jié)練習(xí)中,我們創(chuàng)建這樣一個 parse() 函數(shù):

      # fileparse.py
      def parse(f, types=None, names=None, delimiter=None):
          records = []
          for line in f:
              line = line.strip()
              if not line: continue
              try:
                  records.append(split(line,types,names,delimiter))
              except ValueError as e:
                  print("Couldn't parse :", line)
                  print("Reason :", e)
          return records
      

      請看到 try-except 語句,在 except 塊中,我們應(yīng)該做什么?

      應(yīng)該打印警告消息(warning message)?

      try:
          records.append(split(line,types,names,delimiter))
      except ValueError as e:
          print("Couldn't parse :", line)
          print("Reason :", e)
      

      還是默默忽略警告消息?

      try:
          records.append(split(line,types,names,delimiter))
      except ValueError as e:
          pass
      

      任何一種方式都無法令人滿意,通常情況下,兩種方式我們都需要(用戶可選)。

      使用 logging

      logging 模塊可以解決這個問題:

      # fileparse.py
      import logging
      log = logging.getLogger(__name__)
      
      def parse(f,types=None,names=None,delimiter=None):
          ...
          try:
              records.append(split(line,types,names,delimiter))
          except ValueError as e:
              log.warning("Couldn't parse : %s", line)
              log.debug("Reason : %s", e)
      

      修改代碼以使程序能夠遇到問題的時候發(fā)出警告消息,或者特殊的 Logger 對象。 Logger 對象使用 logging.getLogger(__name__) 創(chuàng)建。

      日志基礎(chǔ)

      創(chuàng)建一個記錄器對象(logger object)。

      log = logging.getLogger(name)   # name is a string
      

      發(fā)出日志消息:

      log.critical(message [, args])
      log.error(message [, args])
      log.warning(message [, args])
      log.info(message [, args])
      log.debug(message [, args])
      

      不同方法代表不同級別的嚴(yán)重性。

      所有的方法都創(chuàng)建格式化的日志消息。args% 運(yùn)算符 一起使用以創(chuàng)建消息。

      logmsg = message % args # Written to the log
      

      日志配置

      配置:

      # main.py
      
      ...
      
      if __name__ == '__main__':
          import logging
          logging.basicConfig(
              filename  = 'app.log',      # Log output file
              level     = logging.INFO,   # Output level
          )
      

      通常,在程序啟動時,日志配置是一次性的(譯注:程序啟動后無法重新配置)。該配置與日志調(diào)用是分開的。

      說明

      日志是可以任意配置的。你可以對日志配置的任何一方面進(jìn)行調(diào)整:如輸出文件,級別,消息格式等等,不必?fù)?dān)心對使用日志模塊的代碼造成影響。

      練習(xí)

      練習(xí) 8.2:將日志添加到模塊中

      fileparse.py 中,有一些與異常有關(guān)的錯誤處理,這些異常是由錯誤輸入引起的。如下所示:

      # fileparse.py
      import csv
      
      def parse_csv(lines, select=None, types=None, has_headers=True, delimiter=',', silence_errors=False):
          '''
          Parse a CSV file into a list of records with type conversion.
          '''
          if select and not has_headers:
              raise RuntimeError('select requires column headers')
      
          rows = csv.reader(lines, delimiter=delimiter)
      
          # Read the file headers (if any)
          headers = next(rows) if has_headers else []
      
          # If specific columns have been selected, make indices for filtering and set output columns
          if select:
              indices = [ headers.index(colname) for colname in select ]
              headers = select
      
          records = []
          for rowno, row in enumerate(rows, 1):
              if not row:     # Skip rows with no data
                  continue
      
              # If specific column indices are selected, pick them out
              if select:
                  row = [ row[index] for index in indices]
      
              # Apply type conversion to the row
              if types:
                  try:
                      row = [func(val) for func, val in zip(types, row)]
                  except ValueError as e:
                      if not silence_errors:
                          print(f"Row {rowno}: Couldn't convert {row}")
                          print(f"Row {rowno}: Reason {e}")
                      continue
      
              # Make a dictionary or a tuple
              if headers:
                  record = dict(zip(headers, row))
              else:
                  record = tuple(row)
              records.append(record)
      
          return records
      

      請注意發(fā)出診斷消息的 print 語句。使用日志操作來替換這些 print 語句相對來說更簡單。請像下面這樣修改代碼:

      # fileparse.py
      import csv
      import logging
      log = logging.getLogger(__name__)
      
      def parse_csv(lines, select=None, types=None, has_headers=True, delimiter=',', silence_errors=False):
          '''
          Parse a CSV file into a list of records with type conversion.
          '''
          if select and not has_headers:
              raise RuntimeError('select requires column headers')
      
          rows = csv.reader(lines, delimiter=delimiter)
      
          # Read the file headers (if any)
          headers = next(rows) if has_headers else []
      
          # If specific columns have been selected, make indices for filtering and set output columns
          if select:
              indices = [ headers.index(colname) for colname in select ]
              headers = select
      
          records = []
          for rowno, row in enumerate(rows, 1):
              if not row:     # Skip rows with no data
                  continue
      
              # If specific column indices are selected, pick them out
              if select:
                  row = [ row[index] for index in indices]
      
              # Apply type conversion to the row
              if types:
                  try:
                      row = [func(val) for func, val in zip(types, row)]
                  except ValueError as e:
                      if not silence_errors:
                          log.warning("Row %d: Couldn't convert %s", rowno, row)
                          log.debug("Row %d: Reason %s", rowno, e)
                      continue
      
              # Make a dictionary or a tuple
              if headers:
                  record = dict(zip(headers, row))
              else:
                  record = tuple(row)
              records.append(record)
      
          return records
      

      完成修改后,嘗試在錯誤的數(shù)據(jù)上使用這些代碼:

      >>> import report
      >>> a = report.read_portfolio('Data/missing.csv')
      Row 4: Bad row: ['MSFT', '', '51.23']
      Row 7: Bad row: ['IBM', '', '70.44']
      >>>
      

      如果你什么都不做,則只會獲得 WARNING 級別以上的日志消息。輸出看起來像簡單的打印語句。但是,如果你配置了日志模塊,你將會獲得有關(guān)日志級別,模塊等其它信息。請按以下步驟操作查看:

      >>> import logging
      >>> logging.basicConfig()
      >>> a = report.read_portfolio('Data/missing.csv')
      WARNING:fileparse:Row 4: Bad row: ['MSFT', '', '51.23']
      WARNING:fileparse:Row 7: Bad row: ['IBM', '', '70.44']
      >>>
      

      你會發(fā)現(xiàn),看不到來自于 log.debug() 操作的輸出。請按以下步驟修改日志級別(譯注:因為日志配置是一次性的,所以該操作需要重啟命令行窗口):

      >>> logging.getLogger('fileparse').level = logging.DEBUG
      >>> a = report.read_portfolio('Data/missing.csv')
      WARNING:fileparse:Row 4: Bad row: ['MSFT', '', '51.23']
      DEBUG:fileparse:Row 4: Reason: invalid literal for int() with base 10: ''
      WARNING:fileparse:Row 7: Bad row: ['IBM', '', '70.44']
      DEBUG:fileparse:Row 7: Reason: invalid literal for int() with base 10: ''
      >>>
      

      只留下 critical 級別的日志消息,關(guān)閉其它級別的日志消息。

      >>> logging.getLogger('fileparse').level=logging.CRITICAL
      >>> a = report.read_portfolio('Data/missing.csv')
      >>>
      

      練習(xí) 8.3:向程序添加日志

      要添加日志到應(yīng)用中,你需要某種機(jī)制來實現(xiàn)在主模塊中初始化日志。其中一種方式使用看起來像下面這樣的代碼:

      # This file sets up basic configuration of the logging module.
      # Change settings here to adjust logging output as needed.
      import logging
      logging.basicConfig(
          filename = 'app.log',            # Name of the log file (omit to use stderr)
          filemode = 'w',                  # File mode (use 'a' to append)
          level    = logging.WARNING,      # Logging level (DEBUG, INFO, WARNING, ERROR, or CRITICAL)
      )
      

      再次說明,你需要將日志配置代碼放到程序啟動步驟中。例如,將其放到 report.py 程序里的什么位置?

      目錄 | 上一節(jié) (8.1 測試) | 下一節(jié) (8.3 調(diào)試)

      注:完整翻譯見 https://github.com/codists/practical-python-zh

      posted @ 2021-04-10 22:55  codists  閱讀(295)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲精品久久久久久下一站| 五月婷婷激情第四季| 一区二区三区在线 | 欧洲 | 性中国videossexo另类| 被灌满精子的少妇视频| 大尺度国产一区二区视频| 黄色段片一区二区三区| av天堂午夜精品一区| 免费无码午夜理论电影| 国产一区二区三区黄色片| 亚洲aⅴ男人的天堂在线观看| 欧美人成精品网站播放| 男女做aj视频免费的网站| 久久美女夜夜骚骚免费视频| 99人体免费视频| 免费现黄频在线观看国产| 国产成人精品2021欧美日韩| 又湿又紧又大又爽A视频男| av在线网站手机播放| 鹤峰县| 国产av综合影院| 99中文字幕国产精品| 1精品啪国产在线观看免费牛牛| 国产成人免费午夜在线观看| 国产精品无遮挡又爽又黄| 毛片免费观看天天干天天爽 | 国产一国产看免费高清片| 激情综合网址| 国产91精品调教在线播放| 久久三级国内外久久三级| 精品国产一区二区三区久久女人| 国产在线啪| 欧美日本精品一本二本三区| 毛片大全真人在线| 午夜精品福利亚洲国产| 在线观看亚洲欧美日本| 一区二区在线观看成人午夜| 不卡AV中文字幕手机看| 亚洲一区二区三区在线观看播放| 思热99re视热频这里只精品| 国产精品人妻久久ai换脸|