1. 程式人生 > >python中常用模塊詳解二

python中常用模塊詳解二

digest cal alt a* bytes byte code 十六 負責

log模塊的講解

技術分享圖片
 1 Python 使用logging模塊記錄日誌涉及四個主要類,使用官方文檔中的概括最為合適:
 2 
 3 logger提供了應用程序可以直接使用的接口API;
 4 handler將(logger創建的)日誌記錄發送到合適的目的輸出;
 5 formatter決定日誌記錄的最終輸出格式
 6 filter提供了細度設備來決定輸出哪條日誌記錄;
 7 
 8 logger
 9 每個程序在輸出信息之前都要獲得一個Logger。Logger通常對應了程序的模塊名,
10 比如聊天工具的圖形界面模塊可以這樣獲得它的Logger:LOG=logging.getLogger(”chat.gui”)
11 12 還可以綁定handler和filters 13 Logger.setLevel(lel):指定最低的日誌級別,低於lel的級別將被忽略。debug是最低的內置級別,critical為最高 14 Logger.addFilter(filt)、Logger.removeFilter(filt):添加或刪除指定的filter 15 Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或刪除指定的handler 16 每個Logger可以附加多個Handler。接下來我們就來介紹一些常用的Handler: 17 logging.StreamHandler 使用這個Handler可以向類似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息。
18 logging.FileHandler 和StreamHandler 類似,用於向一個文件輸出日誌信息。不過FileHandler會幫你打開這個文件 19 logging.handlers.RotatingFileHandler 20 這個Handler類似於上面的FileHandler,但是它可以管理文件大小。 21 當文件達到一定大小之後,它會自動將當前日誌文件改名,然後創建 一個新的同名日誌文件繼續輸出。 22 比如日誌文件是chat.log。當chat.log達到指定的大小之後, 23 RotatingFileHandler自動把 文件改名為chat.log.124 不過,如果chat.log.1已經存在,會先把chat.log.1重命名為chat.log.2。。。
25 最後重新創建 chat.log,繼續輸出日誌信息。 26 函數格式: RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]]) maxBytes最大長度 backupCount保留的文件個數 27 logging.handlers.TimedRotatingFileHandler 28 這個Handler和RotatingFileHandler類似,不過,它沒有通過判斷文件大小來決定何時重新創建日誌文件, 29 而是間隔一定時間就 自動創建新的日誌文件。重命名的過程與RotatingFileHandler類似, 30 不過新的文件不是附加數字,而是當前時間。 31 它的函數是:TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]) 32 when=“S” 秒計算 interveal間隔 backupCount保留的文件個數 33 S 秒 M 分 H 小時 D天 W 每星期(interval==0時代表星期一)midnight 每天淩晨 34 formatter 組件 35 日誌的formatter是個獨立的組件,可以跟handler組合 36 fh = logging.FileHandler("access.log") 37 formatter = logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s) 38 fh.setFormatter(formatter) #把formmater綁定到fh上 39 如果你想對日誌內容進行過濾,就可自定義一個filter 40 class IgnoreBackupLogFilter(logging.Filter): 41 """忽略帶db backup 的日誌""" 42 def filter(self, record): #固定寫法 43 return "db backup" not in record.getMessage() 44 45 # 註意filter函數會返加True or False,logger根據此值決定是否輸出此日誌 46 47 # 然後把這個filter添加到logger中 48 # logger.addFilter(IgnoreBackupLogFilter())
說明解析

 

import logging
from logging import handlers

# 設置一個輸出到屏幕上的handler
log_p_handler = logging.StreamHandler()
# 定義一個輸入文件的handler
log_f_handler = logging.FileHandler("xx.log", encoding="utf8")
# 這個是那日誌截斷的例子,按照長度截斷
log_f_handler_1 = handlers.RotatingFileHandler("xxx.log", maxBytes=10, backupCount=2, encoding="utf8")
log_f_handler_1.setLevel(logging.WARNING)
log_f_handler.setLevel(logging.WARNING)  # 給出入到文件的handler定義一個日誌級別
log_p_handler.setLevel(logging.INFO)  # 給出入到屏幕的handler定義一個日誌級別
fm_p = logging.Formatter("%(asctime)s-%(levelname)s->%(message)s", datefmt="%Y-%m-%d %I:%M:%S")  # 定義兩個格式
fm_f = logging.Formatter("%(asctime)s-%(filename)s-%(levelname)s->%(message)s", datefmt="%Y-%m-%d %I:%M:%S")
# 把格式分別加到 對用的handler中
log_f_handler.setFormatter(fm_f)
log_f_handler_1.setFormatter(fm_f)
log_p_handler.setFormatter(fm_p)
log = logging.getLogger("test")  # 生成一個log接口
# 將自己定義的handler 加到log中
log.addHandler(log_p_handler)
log.addHandler(log_f_handler)
log.addHandler(log_f_handler_1)
# 設置log全局的日誌級別  如果不設置  則默認WARNING級別
log.setLevel(logging.INFO)
log.info("info log")
log.warning("warn log")
log.debug("debug log")

  

subproess模塊提供統一的模塊來實現對系統命令或腳本的調用

# 三種執行命令的方法
# subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs) #官方推薦
# subprocess.call(*popenargs, timeout=None, **kwargs) #跟上面實現的內容差不多,另一種寫法
# #subprocess.Popen() #上面各種方法的底層封裝
# run的標準寫法
import subprocess

subprocess.run([‘df‘, ‘-h‘], stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=True)
# 參數解析:[‘df‘,‘-h‘] 列表 執行命令 subprocess 會拼接起來  stdout 標準輸出=PIPE管道符 check  檢查TRUE則報錯
# 此外還可以跟shell=TRUE  這樣就可以直接寫命令 :
subprocess.run(‘df -h|grep disk1‘, shell=True)  # shell=True的意思是這條命令直接交給系統去執行,不需要python負責解析
# 執行命令,返回命令執行狀態 , 0 or 非0
retcode = subprocess.call(["ls", "-l"])
# 執行命令,如果命令結果為0,就正常返回,否則拋異常
subprocess.check_call(["ls", "-l"])
# 0
# 接收字符串格式命令,返回元組形式,第1個元素是執行狀態,第2個是命令結果
subprocess.getstatusoutput(‘ls /bin/ls‘)
# (0, ‘/bin/ls‘)
# 接收字符串格式命令,並返回結果
subprocess.getoutput(‘ls /bin/ls‘)
# ‘/bin/ls‘
# 執行命令,並返回結果,註意是返回結果,不是打印,下例結果返回給res
res = subprocess.check_output([‘ls‘, ‘-l‘])
# res= b‘total 0\ndrwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM\n‘

# Popen   不會等待命令執行返回結果 而是返回一個句柄 a調用poll()方法可以檢測a的指定狀態
a = subprocess.Popen(‘sleep 10‘, shell=True, stdout=subprocess.PIPE)
#這裏還有其他方法  就不一一贅述了
# a.wait()  a.kill()  a.pid()
# a.send_signal()  a.terminate()

hashlib:用於加密相關的操作,代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

import hashlib
# 用於加密相關的操作,3.x裏代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法


m=hashlib.md5()
m.update(bytes("我", encoding="utf8"))
m.update(b‘it is me ‘)
print("二進制", m.digest())
print("十六進制", m.hexdigest())
#以上加密算法雖然依然非常厲害,但時候存在缺陷,即:通過撞庫可以反解。所以,有必要對加密算法中添加自定義key再來做加密。
print("".center(50,"*"))
m1=hashlib.md5(bytes("生成時加密",encoding="utf8"))
m1.update(bytes("我", encoding="utf8"))
m1.update(b‘it is me ‘)
print("二進制", m.digest())
print("十六進制", m.hexdigest())

re模塊:正則表達式就是字符串的匹配規則,在多數編程語言裏都有相應的支持,python裏對應的模塊是re

技術分享圖片
.     默認匹配除\n之外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
# ‘^‘     匹配字符開頭,若指定flags MULTILINE,這種也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
# ‘$‘     匹配字符結尾, 若指定flags MULTILINE ,re.search(‘foo.$‘,‘foo1\nfoo2\n‘,re.MULTILINE).group() 會匹配到foo1
# ‘*‘     匹配*號前的字符0次或多次, re.search(‘a*‘,‘aaaabac‘)  結果‘aaaa‘
# ‘+‘     匹配前一個字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 結果[‘ab‘, ‘abb‘]
# ‘?‘     匹配前一個字符1次或0次 ,re.search(‘b?‘,‘alex‘).group() 匹配b 0次
# ‘{m}‘   匹配前一個字符m次 ,re.search(‘b{3}‘,‘alexbbbs‘).group()  匹配到‘bbb‘
# ‘{n,m}‘ 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結果‘abb‘, ‘ab‘, ‘abb‘]
# ‘|‘     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結果‘ABC‘
# ‘(...)‘ 分組匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 結果為‘abcabca45‘
# 
# 
# ‘\A‘    只從字符開頭匹配,re.search("\Aabc","alexabc") 是匹配不到的,相當於re.match(‘abc‘,"alexabc") 或^
# ‘\Z‘    匹配字符結尾,同$ 
# ‘\d‘    匹配數字0-9
# ‘\D‘    匹配非數字
# ‘\w‘    匹配[A-Za-z0-9]
# ‘\W‘    匹配非[A-Za-z0-9]
# ‘s‘     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結果 ‘\t‘
# 
# ‘(?P<name>...)‘ 分組匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city")
#  結果{‘province‘: ‘3714‘, ‘city‘: ‘81‘, ‘birthday‘: ‘1993‘}
模式詳解

import re

s = ‘ab23cd121rf‘

res=re.match("[0-9]",s) #從頭開始匹配  匹配一個就結束
print(res)
res = re.search("[0-9]{2}", s)  # 從全部的字符匹配  匹配一個就結束
print(res)  # 對象 取裏面的值則為group  沒有則報錯,那結果之前需要判斷
if res:
    print(res.group())
else:
    print("none!")
print(re.findall("[0-9]", s))  # 匹配所有 符合 就 把它放在列表
print(re.search(".", "aaa"))  # 從開頭一直找 找到 任意字符返回
print(re.search("^a", "aaa"))  # 相當於match(‘a‘)
print(re.search("^ab", "abaab"))  # 相當於match(‘a‘)
print(re.search("ab+$", "abaabb"))  # 從最後開始找。以abb(多個b)結尾的
print(re.search("[a|A]lex","alexAlex"))   #自己的理解就是拿著alex
 #或 Alex在字符裏面找  找到一個滿足就可以
print(re.search("[a|A]lex","aaAlex"))
s = ‘120980199612098769‘
#必須是字符匹配
print(re.search("(\d{6})(\d{4})(\d{4})",s).groups())
#分組匹配的裝逼
print(re.search("(?P<province>\d{6})(?P<year>\d{4})(?P<mothon>\d{4})", s).groupdict())
f = open("聯系方式.txt", encoding="gbk")
data = f.read()
print(data)
f.close()

res = re.findall("(1\d{10})", data)  # 手機號碼
print(res)
s = "alex22jack22rain33"
print(re.split("\d", s))  # 按照一種格式分割
print(re.split("\d+", s))
s1 = "alex22jack22rain33#mock-oldboy"
print(re.split("\d+|#|-", s1))

# 所給字符全部匹配成功則返回字符否則為0
# print(re.fullmatch(‘\w+@\w+\.(com|cn|edu)‘,"[email protected]"))
# 模糊找到需要匹配的字符替換
print(re.sub("[\d+|#|-]", "_", s1))

s = ‘9-2*5/3+7/3*99/4*2998+10*568/14‘
# print(re.split(‘[\*\-/+]‘,s))   #轉義需要\ 來表達
print(re.split(‘[\*\-/+]‘, s, maxsplit=2))  # 轉義需要\ 來表達 maxsplit 匹配前幾個之後停止匹配
# [‘9‘, ‘2‘, ‘5‘, ‘3‘, ‘7‘, ‘3‘, ‘99‘, ‘4‘, ‘2998‘, ‘10‘, ‘568‘, ‘14‘]

  

python中常用模塊詳解二