報警等級python
CRITICAL = 50 # 最高
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0 # 最低
日誌處理本質: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被忽略 ---------------------
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') #
推薦處理日誌方式
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))
注意事項
# 在應用日誌時,若是想要保留異常的堆棧信息。
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)
轉義符
正則表達式中的轉義符在python的字符串中也恰好有轉移的做用可是正則表達式中的轉義符和字符串中的轉義符並不要緊,且還容易有衝突,爲了不這種衝突,咱們全部的正則都以在工具中的測試結果爲結果,而後只須要在正則和待匹配的字符串外面都加r便可
print('\\\\n') # //n
print('\\n') # /n
print(r'\\n') # //n
print(r'\n') # /n
re.findall 匹配字符串中全部規則的項,返回一個列表;未匹配返回一個空列表
import re
ret = re.findall('\d+','asadf451sdfdfb645d')
print(ret) # ['451', '645']
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
re.match 會從頭匹配字符串中取出從第一個字符開始是否符合規則,若是符合,就返回對象,用group取值;若是不符合,就返回None,至關於 match = search + ^正則
import re
ret = re.match('\d+','45adf451sdfdfb645d')
print(ret)
if ret:
print(ret.group())
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 ......
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
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']
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)
分組
findall遇到正則表達式中的分組,會優先顯示分組中的內容
import re
ret = re.findall('\d(\d)','sdfgfgvbnk83')
print(ret) # ['3']
split遇到正則表達式中的分組,會保留分組中原本應該被切割掉的內容
import re
ret1 = re.split('(\d\d)','alex83wusir74taibai') # 默認自動保留分組中的內容
print(ret1) # ['alex', '83', 'wusir', '74', 'taibai']
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
分組命名 (?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分組中的內容
分組引用 (?P=組名) 這個組中的內容必須徹底和以前已經存在的組匹配到的內容如出一轍
import re
s1 = '<h1>wahaha</h1>'
ret = re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',s1)
print(ret.group('tag')) # h1
取消分組優先 (?:)
# 有的時候咱們想匹配的內容包含在不相匹配的內容當中,這個時候只須要把不想匹配的先匹配出來,再經過手段去掉
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']
[] 和 [^] 帶有特殊意義的元字符到字符組內大部分都會取消它的特殊含義
[()+*.]
[(\-
)] -的位置決定了它的意義,寫在字符組的第一位位置或者最後一個位置就表示一個普通的橫槓
寫在字符組的其餘任何位置都會表示一個範圍
練習
# 檢測用戶輸入的內容是不是一個合法的身份證號 網頁的合法輸入(手機號碼 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)