今日主要內容 正則表達式 logging模塊 一、正則表達式 (一)什麼是正則表達式 1. 正則表達式的定義: 是對字元串操作的一種邏輯公式,就是用事先定義好的一些特定字元、及這些特定字元的組合,組成一個“規則字元串”,這個“規則字元串”用來表達對字元串的一種過濾邏輯。 簡單來說,我們使用正則表達式 ...
今日主要內容
- 正則表達式
- logging模塊
一、正則表達式
(一)什麼是正則表達式
- 正則表達式的定義:
- 是對字元串操作的一種邏輯公式,就是用事先定義好的一些特定字元、及這些特定字元的組合,組成一個“規則字元串”,這個“規則字元串”用來表達對字元串的一種過濾邏輯。
- 簡單來說,我們使用正則表達式就是為了對字元串進行 匹配 和 過濾
- 正則表達式的特點:
- 靈活性強、邏輯性強、功能性強
- 可以迅速的用極簡單的方式控制複雜的字元串
(二)正則表達式的構成
- 正則表達式由普通字元和元字元構成
- 普通字元
- 元字元
普通字元
普通字元包括:大小寫字母、數字,在匹配普通字元的時候直接寫就可以了,Python也能實現同樣的效果,很簡單
- 利用
re
模塊,返回正則表達式匹配過濾出來的字元
import re s = "zxdnbzxdnb" print(re.findall("zxd", s)) # 普通字元,直接寫就好了 運行結果: ['zxd', 'zxd'] # 成功匹配過濾
- Python基礎邏輯也可以實現
s = "zxdnbzxdnb" print("zxd" in s) # 是否存在 print(s.count("zxd")) # 存在幾個 print(["zxd"] * 2) # 列印出來就好了 運行結果: True 2 ['zxd', 'zxd'] # 實現同樣的效果
- 利用
元字元
元字元才是正則表達式的靈魂所在,介紹部分內容:
- 字元組
- 常用元字元(單一匹配)
- 量詞
字元組
字元組用
[]
表示,[]
中出現的內容會被匹配到例:匹配到字元串
"zxdhnbzxdznbzxdtnb"
中的"hnb"
"znb"
"tnb"
import re s = "zxdhnbzxdznbzxdtnb" print(re.findall("[hzt]nb", s)) 運行結果: ['hnb', 'znb', 'tnb'] # 將字元串中含有"hnb"、"znb"、"tnb"的部分過濾出來
[]
還可填入一個範圍,比如[0-9a-zA-Z]
它可以匹配字元串中0到9,a到z,A到Z中的字元例:匹配到字元串
"zxd123456zxdznb"
中的數字import re s = "zxd123456zxdznb" print(re.findall("[0-9]", s)) 運行結果: ['1', '2', '3', '4', '5', '6'] # 匹配到字元串中的0到9的數字
範圍遵循ascii碼的從小到大規定,比如
[A-z]
可以匹配之間的所有字元,但[a-Z]
只能匹配到aimport re s = "asdzxcqwe123!@#" print(re.findall("[A-z]", s)) print(re.findall("[a-Z]", s)) 運行結果: ['a', 's', 'd', 'z', 'x', 'c', 'q', 'w', 'e'] # [A-z]匹配成功 sre_constants.error: bad character range a-Z at position 1 # [a-Z]報錯
字元組還可以反向過濾,在
[]
中加入^
,比如[^123]
它可以匹配字元串中除了123以外的所有字元例:匹配到字元串
"zxdznb123456789"
中除數字以外的字元import re s = "zxdznb123456789" print(re.findall("[^0-9]", s)) 運行結果: ['z', 'x', 'd', 'z', 'n', 'b'] # 匹配到字元串中除數字以外的字元
應用舉例:通過匹配判斷手機號輸入是否正確(有點low的例子)
import re number = input("手機號:") if len(number) != 11: print("手機號輸入有誤!") else: num = re.findall("[1][3-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]", number) if not num: print("手機號格式不正確!") else: print("手機號可以使用!")
常用元字元(單一匹配)
\w 匹配字母(含中文)、數字、下劃線 \W 匹配非字母(含中文)、數字、下劃線 \s 匹配空白符 \S 匹配非空白符 \d 匹配數字 \D 匹配非數字 \b 匹配單詞的邊界 \B 匹配非單詞的邊界 \A 匹配字元串的開始 ^ 匹配字元串的開始 \Z 匹配字元串的結尾 $ 匹配字元串的結尾 \n 匹配一個換行符 \t 匹配一個製表符 . 匹配除換行符以外任意字元 a|b 匹配字元a或b () 分組,匹配括弧內的表達式 [] 匹配字元組內的字元 [^] 匹配除字元組以外的字元 \w :匹配字元串中字母(含中文)、數字、下劃線
例:匹配到字元串
"zxd123\n456!@#¥"
中的字母和數字import re s = "zxd123\n456!@#¥" print(re.findall("\w", s)) 運行結果: ['z', 'x', 'd', '1', '2', '3', '4', '5', '6']
\W :匹配字元串中非字母(含中文)、數字、下劃線
例:匹配到字元串
"zxd123\n456!@#¥"
中的非字母和數字的內容import re s = "zxd123\n456!@#¥" print(re.findall("\W", s)) 運行結果: ['\n', '!', '@', '#', '¥']
\s :匹配空白符(包含空格、製表符和換行符 )
例:匹配到字元串
"zxd \t123 \n456 !@#¥"
中的空白符import re s = "zxd \t123 \n456 !@#¥" print(re.findall("\s", s)) 運行結果: [' ', ' ', '\t', ' ', ' ', '\n', ' ', ' ']
\S :匹配非空白符
例:匹配到字元串
"zxd \t123 \n456 !@#¥"
中非空白符的內容import re s = "zxd \t123 \n456 !@#¥" print(re.findall("\S", s)) 運行結果: ['z', 'x', 'd', '1', '2', '3', '4', '5', '6', '!', '@', '#', '¥']
\d :匹配數字
例:匹配到字元串
"zxd123456zxdznb"
中的數字import re s = "zxd123456zxdznb" print(re.findall("\d", s)) 運行結果: ['1', '2', '3', '4', '5', '6']
\D :匹配非數字
例:匹配到字元串
"zxd123456zxdznb"
中的非數字的內容import re s = "zxd123456zxdznb" print(re.findall("\D", s)) 運行結果: ['z', 'x', 'd', 'z', 'x', 'd', 'z', 'n', 'b']
\b :匹配單詞邊界
例:匹配到字元串
"周傑倫-麻花藤-潘長江-趙本山-林俊周-韓周鴻-周猩猩-周星"
中所有姓周的人名import re s = "周傑倫-麻花藤-潘長江-趙本山-林俊周-韓周鴻-周猩猩-周星" print(re.findall(r"\b周\w+", s)) 運行結果: ['周傑倫', '周猩猩', '周星']
\B :匹配非單詞邊界
例:匹配到字元串
"周傑倫-麻花藤-潘長江-趙本山-林俊周-韓周鴻-周猩猩-周星"
中所有名帶有周的人import re s = "周傑倫-麻花藤-潘長江-趙本山-林俊周-韓周鴻-周猩猩-周星" print(re.findall(r"\w+\B周\w*", s)) 運行結果: ['林俊周', '韓周鴻']
\A :匹配字元串的開頭(不常用,知道就行)
例:匹配到字元串
"zxdhnbzxdznb"
的開頭import re s = "zxdhnbzxdznb" print(re.findall("\A\w", s)) 運行結果: ['z']
^ :匹配字元串的開頭(常用)
例:匹配到字元串
"zxdhnbzxdznb"
的開頭import re s = "zxdhnbzxdznb" print(re.findall("^\w", s)) 運行結果: ['z']
\Z :匹配字元串的結尾(不常用,知道就行)
例:匹配到字元串
"zxdhnbzxdznb"
的結尾import re s = "zxdhnbzxdznb" print(re.findall("\w\Z", s)) 運行結果: ['b']
$ :匹配字元串的結尾(常用)
例:匹配到字元串
"zxdhnbzxdznb"
的結尾import re s = "zxdhnbzxdznb" print(re.findall("\w$", s)) 運行結果: ['b']
^ 和 $ 結合使用時,兩者之間的長度一定要和待匹配的字元串長度相同,否則匹配不上
import re s = "zxdznb666" print(re.findall("^zxdznb666$", s)) print(re.findall("^zxdznb$", s)) 運行結果: ['zxdznb666'] []
^ 和 $ 的應用舉例:通過匹配判斷手機號輸入是否正確(升級版,還是很low)
import re number = input("手機號:") num = re.findall("^[1][3-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$", number) # 匹配到以1開頭,以0到9結尾的一串11位數字 if not num: print("手機號格式不正確!") else: print("手機號可以使用!")
\n :匹配換行符
例:匹配到字元串
"zxd \t123 \n456 !@#$"
中的換行符import re s = "zxd \t123 \n456 !@#$" print(re.findall("\n", s)) 運行結果: ['\n']
\t :匹配製表符
例:匹配到字元串
"zxd \t123 \n456 !@#$"
中的製表符import re s = "zxd \t123 \n456 !@#$" print(re.findall("\t", s)) 運行結果: ['\t']
. :匹配除換行符任意的字元,當指定
re.DOTALL
時,可以匹配含換行符以內的任意字元例:匹配字元串
"zxd123\n456"
中所有內容(含換行符|不含換行符)import re s = "zxd123\n456" print(re.findall(".", s)) print(re.findall(".", s, re.DOTALL)) 運行結果: ['z', 'x', 'd', '1', '2', '3', '4', '5', '6'] ['z', 'x', 'd', '1', '2', '3', '\n', '4', '5', '6']
a|b :匹配字元a或b,優先匹配前面,只要前面匹配到了後面就不看了,繼續向下匹配
例:匹配到字元串
"zxdnb666zxd"
中的zxd
和666
import re s = "zxdnb666zxd" print(re.findall("zxd|666", s)) 運行結果: ['zxd', '666', 'zxd']
() :分組,匹配括弧內的表達式,可以在括弧兩端增加限制
例:匹配到字元串
"zxdnb66zxd66zxd"
中的zxd
,只匹配到66中間的zxd
import re s = "zxdnb66zxd66zxd" print(re.findall("(zxd)", s)) print(re.findall("66(zxd)66", s)) 運行結果: ['zxd', 'zxd', 'zxd'] ['zxd']
[] :匹配字元組範圍內的字元
[^] :匹配非字元組範圍內的字元
量詞(多個匹配)
***** 重覆零次或更多次 + 重覆一次或更多次 ? 重覆零次或一次 {n} 重覆n次 {n,} 重覆n次或更多次 {n,m} 重覆n到m次 - ***** :重覆零次或更多次
import re s = "zxdnb66zxd66zxd" print(re.findall("6*", s)) 運行結果: ['', '', '', '', '', '66', '', '', '', '66', '', '', '', '']
- + :重覆一次或更多次
import re s = "zxdnb66zxd66zxd" print(re.findall("6+", s)) 運行結果: ['66', '66']
- ?:重覆零次或一次
import re s = "zxdnb66zxd66zxd" print(re.findall("6?", s)) 運行結果: ['', '', '', '', '', '6', '6', '', '', '', '6', '6', '', '', '', '']
- {n} :重覆n次
import re s = "zxdnb66zxd66zxd" print(re.findall("\w{3}", s)) 運行結果: ['zxd', 'nb6', '6zx', 'd66', 'zxd']
- {n,} :重覆n次或更多次
import re s = "zxdnb66-zxd-6-6zxd" print(re.findall("\w{3,}", s)) 運行結果: ['zxdnb66', 'zxd', '6zxd']
- {n,m} :重覆n到m次
import re s = "zxdnb66-zxd-6-6zxd" print(re.findall("\w{3,5}", s)) 運行結果: ['zxdnb', 'zxd', '6zxd']
- {} 的應用舉例:通過匹配判斷手機號輸入是否正確(再次升級版)
import re number = input("手機號:") num = re.findall("^[1][3-9][0-9]{9}$", number) # 匹配到以1開頭,以0到9結尾的一串11位數字 if not num: print("手機號格式不正確!") else: print("手機號可以使用!")
貪婪匹配和非貪婪匹配(惰性匹配)
貪婪匹配:儘可能多的匹配,量詞中的
* + {}
都是貪婪匹配import re s = "zxdznb666" print(re.findall("\w*", s)) print(re.findall("\w+", s)) print(re.findall("\w{1,3}", s)) 運行結果: ['zxdznb666', ''] ['zxdznb666'] ['zxd', 'znb', '666']
- 貪婪匹配底層運用到的演算法:回溯演算法
非貪婪匹配(惰性匹配):儘可能少的匹配,量詞中的
?
是非貪婪匹配import re s = "zxdznb666" print(re.findall("\w{1,3}?", s)) 運行結果: ['z', 'x', 'd', 'z', 'n', 'b', '6', '6', '6']
- 非貪婪匹配底層用到的演算法:先去找結束的值,再去判斷規則
轉義:定義規則時,會遇到類似於\n這樣的具有特殊意義的詞,可以使用轉義表示,轉義有兩種方式:
- 方式一:
\\n
- 方式二:
r"\n"
- 方式一:
(三)正則模塊re
核心方法:
re.findall() 按規則查找,返回list re,finditer() 按規則查找,返回一個迭代器,通過group方法取值 re.search() 任意位置匹配,匹配到就返回結果,沒匹配上返回None re.match() 只能從字元串開頭開始匹配,匹配到就返回結果,匹配不到返回None re.findall()
- 函數定義:
findall(pattern, string, flags=0)
- 函數說明:按規則查找,返回一個列表
import re s = "zxd123\n456!@#¥" print(re.findall("\w", s)) 運行結果: ['z', 'x', 'd', '1', '2', '3', '4', '5', '6']
- 函數定義:
re,finditer()
- 函數定義:
finditer(pattern, string, flags=0)
- 函數說明:按規則查找,返回一個迭代器,通過group方法取值
import re s = "zxd" it = re.finditer("\w", s) for el in it: print(el.group()) 運行結果: z x d
- 函數定義:
re.search()
- 函數定義:
search(pattern, string, flags=0)
- 函數說明:任意位置匹配,匹配到就返回結果,沒匹配上返回None
import re s = "zxdnb66-zxd-6-6zxd" print(re.search(r"\w+", s).group()) 運行結果: zxdnb66
- 還可以給分組起名稱,利用名稱輸出
- 格式為:
?P<名稱>
- 格式為:
import re s = "<h1>hello</h1>" ret = re.search("<(?P<h>\w+)>(?P<h1>\w+)</(?P<h2>\w+)>",s) print(ret.group("h")) print(ret.group("h1")) print(ret.group("h2")) 運行結果: h1 hello h1
- 函數定義:
re.match()
- 函數定義:
match(pattern, string, flags=0)
- 函數說明:只能從字元串開頭開始匹配,匹配到就返回結果,匹配不到返回None
import re s = "zxdnb66-zxd-6-6zxd" print(re.match(r"\w+", s).group()) s = "-zxdnb66-zxd-6-6zxd" print(re.match(r"\w+", s)) 運行結果: zxdnb66 None
- 函數定義:
其他方法
re.split() 可按照任意分隔符進行分隔 re.sub() 替換 re.compile() 編譯規則 re.split()
- 函數定義:
split(pattern, string, maxsplit=0, flags=0)
- 函數說明:按照填入的參數進行切割,返回一個列表,將填入的參數用括弧括起來,則在返回的列表中保留切割參數,還可指定最大切割次數,剩餘部分作為最後一個元素存放在列表中
import re s = "zxd-nb-666-777-888" print(re.split("-", s)) print(re.split("(-)", s)) print(re.split("-", s, maxsplit=2)) 運行結果: ['zxd', 'nb', '666', '777', '888'] ['zxd', '-', 'nb', '-', '666', '-', '777', '-', '888'] ['zxd', 'nb', '666-777-888']
- 函數定義:
re.sub()
- 函數定義:
sub(pattern, repl, string, count=0, flags=0)
- 函數說明:替換,可以通過count控制替換次數
import re s = "zxd-nb-666-777-888" print(re.sub("-", "|", s)) print(re.sub("-", "|", s, 2)) 運行結果: zxd|nb|666|777|888 zxd|nb|666-777-888
- 函數定義:
re.compile()
- 函數定義:
compile(pattern, flags=0)
- 函數說明:編譯一個正則表達式,返回一個規則對象
import re s = "zxd-nb-666-777-888" obj = re.compile("\w+") print(obj.findall(s)) 運行結果: ['zxd', 'nb', '666', '777', '888']
- 函數定義:
二、logging模塊
(一)什麼是日誌
- 我們在編寫代碼的時候,會報很多的錯誤,錯誤信息是不會自動生成的,這些錯誤信息是編寫python解釋器的程式員們預先寫好的日誌加入到程式中,如過觸發了某種條件會顯示到中控臺上,我們在寫程式的過程中也會不斷調試,我們調試的方法一般都是使用
print
列印出來,這就可以通過日誌顯示和記錄 - 在python中使用logging模塊就可以自定義日誌,在我們編寫程式的時候,就可以利用自定義日誌來進行顯示和記錄
- 最重要的一點,日誌是給程式員看的,需要給用戶看的還是需要print出來
(二)logging模塊
logging模塊的使用:
- 基礎配置型:簡單、可定製化差
- 對象配置型:複雜、可定製化強
日誌分級
日誌分級 對應解釋 級別數值 debug 調試 10 info 信息 20 warning 警告 30 error 錯誤 40 critical 危險 50 函數式簡單配置
- 基礎版日誌
import logging logging.debug('debug message') # 調試 logging.info('info message') # 信息 logging.warning('warning message') # 警告 logging.error('error message') # 錯誤 logging.critical('critical message') # 危險 運行結果: WARNING:root:warning message ERROR:root:error message CRITICAL:root:critical message
說明:
- 運行時顯示的的結果只有
warning
、error
、critical
三個級別的日誌信息,logging模塊預設從warning
級別(30)的日誌開始輸出 - 輸出的日誌由日誌級別、用戶名、日誌信息三部分構成
- 運行時顯示的的結果只有
通過日誌配置函數
logging.basicConfig()
可以調整輸出級別、日誌內容等信息,配置函數如下:- 函數定義:
basicConfig(**kwargs)
- 關鍵字參數說明:
filename 指定文件,日誌內容將會存儲在文件中 filemode 文件打開方式,指定了filename後才能指定,預設為"a" format 日誌顯示格式,參數如下 datefmt 時間顯示格式 level 日誌級別 - format 參數說明:
%(name)s Logger的名字 %(levelno)s 數字形式的日誌級別 %(levelname)s 文本形式的日誌級別 %(pathname)s 調用日誌輸出函數的模塊的完整路徑名,可能沒有 %(filename)s 調用日誌輸出函數的模塊的文件名 %(module)s 調用日誌輸出函數的模塊名 %(funcName)s 調用日誌輸出函數的函數名 %(lineno)d 調用日誌輸出函數的語句所在的代碼行 %(created)f 當前時間,用UNIX標準的表示時間的浮點數表示 %(relativeCreated)d 輸出日誌信息時,自Logger創建以來的毫秒數 %(asctime)s 字元串形式的當前時間。預設格式是 “2003-07-08 16:49:45,896”。 %(thread)d 線程ID。可能沒有 %(threadName)s 線程名。可能沒有 %(process)d 進程ID。可能沒有 %(message)s 用戶輸出的消息 - 舉例:
import logging logging.basicConfig(level=logging.DEBUG, # 調整日誌輸出等級 format="Time:'%(asctime)s' FilePath:'%(pathname)s' [line:%(lineno)d] %(levelname)s Message:'%(message)s'", datefmt='%Y-%m-%d %H:%M:%S') logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') 運行結果: Time:'2019-10-03 15:09:06' FilePath:'D:/python_S26/day17/exercise.py' [line:226] DEBUG Message:'debug message' Time:'2019-10-03 15:09:06' FilePath:'D:/python_S26/day17/exercise.py' [line:227] INFO Message:'info message' Time:'2019-10-03 15:09:06' FilePath:'D:/python_S26/day17/exercise.py' [line:228] WARNING Message:'warning message' Time:'2019-10-03 15:09:06' FilePath:'D:/python_S26/day17/exercise.py' [line:229] ERROR Message:'error message' Time:'2019-10-03 15:09:06' FilePath:'D:/python_S26/day17/exercise.py' [line:230] CRITICAL Message:'critical message'
- 函數定義:
列舉三個應用,理解日誌的用法
logging.debug()
的應用
import logging logging.basicConfig(level=logging.DEBUG, # 這裡可以通過修改輸出等級來控制需要調試的時候輸出 format="Time:'%(asctime)s' FilePath:'%(pathname)s' [line:%(lineno)d] %(levelname)s Message:'%(message)s'", datefmt='%Y-%m-%d %H:%M:%S') lst = list() for el in range(5): lst.append(el) logging.debug(lst) print(lst) 運行結果: [0, 1, 2, 3, 4] # 併發問題導致先輸出lst Time:'2019-10-03 17:16:49' FilePath:'D:/python_S26/day17/exercise.py' [line:239] DEBUG Message:'[0]' Time:'2019-10-03 17:16:49' FilePath:'D:/python_S26/day17/exercise.py' [line:239] DEBUG Message:'[0, 1]' Time:'2019-10-03 17:16:49' FilePath:'D:/python_S26/day17/exercise.py' [line:239] DEBUG Message:'[0, 1, 2]' Time:'2019-10-03 17:16:49' FilePath:'D:/python_S26/day17/exercise.py' [line:239] DEBUG Message:'[0, 1, 2, 3]' Time:'2019-10-03 17:16:49' FilePath:'D:/python_S26/day17/exercise.py' [line:239] DEBUG Message:'[0, 1, 2, 3, 4]'
logging.info()
的應用
import logging logging.basicConfig(level=logging.INFO, format="Time:'%(asctime)s' FilePath:'%(pathname)s' [line:%(lineno)d] %(levelname)s Message:'%(message)s'", datefmt='%Y-%m-%d %H:%M:%S') userinfo = dict() user = input("賬號:") pwd = input("密碼:") userinfo[user] = pwd logging.info(f"註冊的賬號:{user},註冊的密碼:{pwd}") # 記錄程式運行時的信息 運行結果: 賬號:zxd 密碼:zxd123 Time:'2019-10-03 17:35:07' FilePath:'D:/python_S26/day17/exercise.py' [line:251] INFO Message:'註冊的賬號:zxd,註冊的密碼:zxd123'
logging.error()
的應用
import logging logging.basicConfig(level=logging.INFO, format="Time:'%(asctime)s' FilePath:'%(pathname)s' [line:%(lineno)d] %(levelname)s Message:'%(message)s'", datefmt='%Y-%m-%d %H:%M:%S') try: def division(a, b): c = a / b return c division(3, 0) except ZeroDivisionError: print("除數不能為0") logging.error("輸入除數為0") 運行結果: 除數不能為0 Time:'2019-10-03 17:51:46' FilePath:'D:/python_S26/day17/exercise.py' [line:266] ERROR Message:'輸入除數為0'
函數式簡單配置有兩個弊端:
- 編碼不能修改
- 中控台和文件不能同時進行(要麼在中控台顯示,要麼寫入文件)
logger對象配置
- 利用logger對象來操作日誌文件,具體流程如下:
- 創建一個logger對象,用來操作日誌
- 創建一個文件管理操作符,用來寫入文件
- 創建一個屏幕管理操縱符, 用來屏幕顯示
- 創建一個日誌輸出的格式
- 將操作符與輸出格式進行綁定
- 將logger對象與操作符進行綁定
import logging logger = logging.getLogger() # 創建一個logger對象,用來操作日誌 fh = logging.FileHandler("log.log", encoding="utf-8") # 創建一個文件管理操作符,用來寫入文件 sh = logging.StreamHandler() # 創建一個屏幕管理操縱符, 用來屏幕顯示 fmt = logging.Formatter("Time:'%(asctime)s' FilePath:'%(pathname)s' [line:%(lineno)d] %(levelname)s Message:'%(message)s'") # 創建一個日誌輸出的格式 fh.setFormatter(fmt) # 將文件管理操作符與輸出格式進行綁定 sh.setFormatter(fmt) # 將屏幕管理操作符與輸出格式進行綁定 logger.addHandler(fh) # 將logger對象與文件管理操作符進行綁定 logger.addHandler(sh) # 將logger對象與屏幕管理操作符進行綁定 logger.setLevel(logging.DEBUG) # 調整日誌輸出級別 logger.debug('debug message') logger.info('info message') logger.warning('warning message') logger.error('error message') logger.critical('critical message') 運行結果: Time:'2019-10-03 18:31:18,217' FilePath:'D:/python_S26/day17/exercise.py' [line:283] DEBUG Message:'debug message' Time:'2019-10-03 18:31:18,217' FilePath:'D:/python_S26/day17/exercise.py' [line:284] INFO Message:'info message' Time:'2019-10-03 18:31:18,217' FilePath:'D:/python_S26/day17/exercise.py' [line:285] WARNING Message:'warning message' Time:'2019-10-03 18:31:18,217' FilePath:'D:/python_S26/day17/exercise.py' [line:286] ERROR Message:'error message' Time:'2019-10-03 18:31:18,218' FilePath:'D:/python_S26/day17/exercise.py' [line:287] CRITICAL Message:'critical message'
- 說明:
- 通過logger對象來操作日誌可以讓中控台和文件同時進行
- 通過logger對象寫入文件時,可以指定編碼方式
- 靈活性高,創建的對象之間沒有關係,通過綁定鏈在一起,完全可以綁定兩個文件管理操作符來寫入不同的文件,也可以綁定不同的輸出格式
- 利用logger對象來操作日誌文件,具體流程如下: