第五章 模塊之 logging、copy、re

5.12 logging 日誌模塊

  1. 報警等級python

    CRITICAL = 50 # 最高
    FATAL = CRITICAL
    ERROR = 40
    WARNING = 30
    WARN = WARNING
    INFO = 20
    DEBUG = 10
    NOTSET = 0 # 最低
  2. 日誌處理本質:Logger/FileHandler/Formatter正則表達式

    應用:統計用;作故障排除debug;記錄錯誤,完成代碼優化ide

    # 示例一
    import logging
    ​
    file_handler1 = logging.FileHandler('x2.log', 'a', encoding='utf-8')    # 構造參數
    fmt1 = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
    file_handler1.setFormatter(fmt1)
    ​
    # file_handler2 = logging.FileHandler('x2.log', 'a', encoding='utf-8')
    # fmt2 = logging.Formatter(fmt="%(asctime)s:  %(message)s")
    # file_handler2.setFormatter(fmt2)
    ​
    logger = logging.Logger('xxxxxx', level=logging.ERROR)
    logger.addHandler(file_handler1)
    # logger.addHandler(file_handler2)
    # 示例二
    import logging
    ​
    logging.basicConfig(    # 函數各參數
        filename='cmdb1.log',   # 日誌文件名稱
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',  # 指定日誌輸出格式和內容
        datefmt='%Y-%m-%d %H:%M:%S %p', # 指定時間格式
        level=logging.ERROR # 日誌報警等級
    )
    ​
    # 無效    日誌只配置一次
    logging.basicConfig(
        filename='cmdb2.log',
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        level=logging.ERROR
    )
    ​
    logging.error('alex')   # 報警內容
    ​
    ​
    logging.basicConfig函數各參數:
    filename: 指定日誌文件名
    filemode: 和file函數意義相同,指定日誌文件的打開模式,'w''a'
    format: 指定輸出的格式和內容,format能夠輸出不少有用信息,如上例所示:
     %(levelno)s: 打印日誌級別的數值
     %(levelname)s: 打印日誌級別名稱
     %(pathname)s: 打印當前執行程序的路徑,其實就是sys.argv[0]
     %(filename)s: 打印當前執行程序名
     %(funcName)s: 打印日誌的當前函數
     %(lineno)d: 打印日誌的當前行號
     %(asctime)s: 打印日誌的時間
     %(thread)d: 打印線程ID
     %(threadName)s: 打印線程名稱
     %(process)d: 打印進程ID
     %(message)s: 打印日誌信息
    datefmt: 指定時間格式,同time.strftime()
    level: 設置日誌級別,默認爲logging.WARNING
    stream: 指定將日誌的輸出流,能夠指定輸出到sys.stderr,sys.stdout或者文件,默認輸出到sys.stderr,當stream和filename同時指定時,stream被忽略
    --------------------- 
    View Code

     

    logging.basicconfig函數

    • 使用方便工具

    • 不能實現編碼問題;不能同時向文件和屏幕輸出測試

    • logging.debug logging.warning優化

    logger對象 複雜的建立流程ui

    • 建立一個logger對象編碼

    • 建立一個文件操做符spa

    • 建立一個屏幕操做符

    • 建立一個格式

    操做;

    • 給logger對象綁定 文件操做符

    • 給logger對象綁定 屏幕操做符

    • 給文件操做符設定格式

    • 給屏幕操做符設定格式

      import logging

      logger = logging.getLogger() # 建立一個logger對象
      fh = logging.FileHandler('log.log') # 建立一個文件操做符
      sh = logging.StreamHandler() # 建立一個屏幕操做符
      logger.addHandler(fh) # 給logger對象綁定 文件操做符
      logger.addHandler(sh) # 給logger對象綁定 屏幕操做符
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 建立一個格式
      fh.setFormatter(formatter) # 給文件操做符設定格式
      sh.setFormatter(formatter) # 給屏幕操做符設定格式
      logger.warning('message') #

       

  3. 推薦處理日誌方式

    import logging

    file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
    logging.basicConfig(
       format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
       datefmt='%Y-%m-%d %H:%M:%S %p',
       handlers=[file_handler,],
       level=logging.ERROR
    )

    logging.error('你好')
    # 日誌切割
    import time
    import logging
    from logging import handlers
    # file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
    file_handler = handlers.TimedRotatingFileHandler(filename='x3.log', when='s', interval=5, encoding='utf-8')
    logging.basicConfig(
       format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
       datefmt='%Y-%m-%d %H:%M:%S %p',
       handlers=[file_handler,],
       level=logging.ERROR
    )

    for i in range(1,100000):
       time.sleep(1)
       logging.error(str(i))
  4. 注意事項

    # 在應用日誌時,若是想要保留異常的堆棧信息。
    import logging
    import requests

    logging.basicConfig(
       filename='wf.log',
       format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
       datefmt='%Y-%m-%d %H:%M:%S %p',
       level=logging.ERROR
    )

    try:
       requests.get('http://www.xxx.com')
    except Exception as e:
       msg = str(e) # 調用e.__str__方法
       logging.error(msg,exc_info=True)

     

5.13 copy

 

5.14 re模塊

  1. 轉義符

    正則表達式中的轉義符在python的字符串中也恰好有轉移的做用可是正則表達式中的轉義符和字符串中的轉義符並不要緊,且還容易有衝突,爲了不這種衝突,咱們全部的正則都以在工具中的測試結果爲結果,而後只須要在正則和待匹配的字符串外面都加r便可

    print('\\\\n') # //n
    print('\\n') # /n

    print(r'\\n') # //n
    print(r'\n') # /n
  2. re.findall 匹配字符串中全部規則的項,返回一個列表;未匹配返回一個空列表

    import re

    ret = re.findall('\d+','asadf451sdfdfb645d')
    print(ret) # ['451', '645']
  3. re.search 會從頭至尾從帶匹配,匹配字符串取出第一個符合條件的項,若是匹配到了,返回一個對象,用group取值;若是沒匹配到,返回None,不能用group,會報錯

    import re
    ret = re.search('\d+','asadf451sdfdfb645d')
    print(ret) # <_sre.SRE_Match object; span=(5, 8), match='451'> span 是索引 match 是匹配到的項
    if ret:
       print(ret.group()) # 451
  4. re.match 會從頭匹配字符串中取出從第一個字符開始是否符合規則,若是符合,就返回對象,用group取值;若是不符合,就返回None,至關於 match = search + ^正則

    import re

    ret = re.match('\d+','45adf451sdfdfb645d')
    print(ret)
    if ret:
       print(ret.group())
  5. re.finditer 在查詢的結果超過1個的狀況下,可以有效的節省內存,下降空間複雜度,從而也下降了時間複雜度

    import re

    ret = re.finditer("\d+",'cdfz56x31d144df'*1000)
    print(ret) # <callable_iterator object at 0x000002541A7874A8>   迭代器
    for i in ret: # 循環迭代出每一個元素
       print(i.group()) # 56   31   144 ......
  6. compile 在同一個正則表達式重複使用屢次的時候使用可以減小時間的開銷,屬於內置函數

    import re

    ret = re.compile('\d+')
    print(ret) # re.compile('\\d+')
    r1 = ret.search('alex83')
    print(r1) # <_sre.SRE_Match object; span=(4, 6), match='83'>
    r2 = ret.findall('wusir74')
    print(r2) # ['74']
    r3 = ret.finditer('taibai40')
    for i in r3:
       print(i.group()) # 40
  7. re.split() 分割,根據正則規則切割,返回列表,默認不保留切掉的內容

    import re
    ret1 = re.split('\d\d','alex83wusir74taibai')  # 默認自動保留分組中的內容
    print(ret1) # ['alex', 'wusir', 'taibai']

    ret2 = re.split('\d(\d)','alex83wusir74taibai')
    print(ret2) # ['alex', '3', 'wusir', '4', 'taibai']
  8. re.sub() 替換,默認替換全部,可使用替換深度參數

    re.subn() 替換,返回元祖

    import re

    ret1 = re.sub('\d','D','alex83wusir74taibai')
    print(ret1) # alexDDwusirDDtaibai

    ret2 = re.sub('\d','D','alex83wusir74taibai',1)
    print(ret2) # alexD3wusir74taibai

    ret3 = re.subn('\d','D','alex83wusir74taibai')
    print(ret3) # ('alexDDwusirDDtaibai', 4)
  9. 分組

    1. findall遇到正則表達式中的分組,會優先顯示分組中的內容

      import re

      ret = re.findall('\d(\d)','sdfgfgvbnk83')
      print(ret) # ['3']
    2. split遇到正則表達式中的分組,會保留分組中原本應該被切割掉的內容

      import re
      ret1 = re.split('(\d\d)','alex83wusir74taibai')  # 默認自動保留分組中的內容
      print(ret1) # ['alex', '83', 'wusir', '74', 'taibai']
    3. group(加參數)

      s1 = '<h1>wahaha</h1>'
      ret = re.search('<(\w+)>(.*?)</\w+>',s1)
      print(ret) # <_sre.SRE_Match object; span=(0, 15), match='<h1>wahaha</h1>'>
      print(ret.group(0))   # group參數默認爲0 表示取整個正則匹配的結果 <h1>wahaha</h1>
      print(ret.group(1))   # 取第一個分組中的內容 h1
      print(ret.group(2))   # 取第二個分組中的內容 wahaha  
    4. 分組命名 (?P<名字>正則表達式)

      search 取分組中的內容 經過索引;經過組名取

      s1 = '<h1>wahaha</h1>'
      ret = re.search('<(?P<tag>\w+)>(?P<cont>.*?)</\w+>',s1)
      print(ret) # <_sre.SRE_Match object; span=(0, 15), match='<h1>wahaha</h1>'>
      print(ret.group(0))   # group參數默認爲0 表示取整個正則匹配的結果 <h1>wahaha</h1>
      pprint(ret.group('tag'))   # 取tag分組中的內容
      print(ret.group('cont'))   # 取cont分組中的內容
    5. 分組引用 (?P=組名) 這個組中的內容必須徹底和以前已經存在的組匹配到的內容如出一轍

      import re

      s1 = '<h1>wahaha</h1>'
      ret = re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',s1)
      print(ret.group('tag')) # h1
    6. 取消分組優先 (?:)

      # 有的時候咱們想匹配的內容包含在不相匹配的內容當中,這個時候只須要把不想匹配的先匹配出來,再經過手段去掉
      import re
      ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
      print(ret) # ['1', '2', '60', '', '5', '4', '3']
      ret.remove('')
      print(ret) # ['1', '2', '60', '5', '4', '3']
  10. [] 和 [^] 帶有特殊意義的元字符到字符組內大部分都會取消它的特殊含義

    • [()+*.]

      • [(\-)] -的位置決定了它的意義,寫在字符組的第一位位置或者最後一個位置就表示一個普通的橫槓

      • 寫在字符組的其餘任何位置都會表示一個範圍

    • 練習

      # 檢測用戶輸入的內容是不是一個合法的身份證號     網頁的合法輸入(手機號碼 qq號碼 銀行卡號 郵箱地址)
      '^[1-9]\d{14}(\d{2}[\dx])?$'
      import re
      inp = input('>>>').strip()
      re.match('[1-9]\d{14}(\d{2}[\dx])?$',inp)   # 首選
      re.search('^[1-9]\d{14}(\d{2}[\dx])?$',inp)
      re.findall('^[1-9]\d{14}(\d{2}[\dx])?$',inp)
相關文章
相關標籤/搜索