巨蟒python全棧開發-第20天 核能來襲-約束 異常處理 MD5 日誌處理
阿新 • • 發佈:2018-12-21
一.今日主要內容
1.類的約束(對下面人的程式碼進行限制;專案經理的必備技能,要想走的長遠)
(1)寫一個父類,父類中的某個方法要丟擲一個異常 NotImplementedError(重點)
(2)抽象類和抽象方法
from abc import ABCMeta,abstractmethod
class Base (metaclass=ABCMeta):
@abstractmethod
def fangfa(self):
pass
2.異常處理. try except raise
(1)try:
程式碼
except 異常類:
出了錯,如何處理異常
except 異常類:
出了錯,如何處理異常
except 異常類:
出了錯,如何處理異常
except 異常類:
出了錯,如何處理異常
else:
當程式不出錯
finally:
不管出不出差,都要執行
(2)raise 異常類('資訊')
如何自己定義異常?
class 類(Exception): #異常的最根本的父類Exception
pass #我們可以自己定義異常類
(3)堆疊(備註:traceback:回溯;追溯;追蹤;錯誤訊息與追溯)#拿堆疊資訊
import traceback
traceback.format_exc()
3.MD5加密(4句話搞定MD5)
(1)#注意:鹽和要加密的內容必須,都是bytes
(2)如果有多個update,多個update是一起算的
import hashlib
obj=hashlib.md5(b'鹽') #不要改鹽,改了鹽資料庫中的儲存資訊就全部蹦了
obj.update(b'要加密的內容')
print(obj.hexdigest()) #加鹽後的結果
4.日誌處理 (重點價值:不要記,留一份,側重點在用上)
(沒問題的時候,註釋和日誌,沒有任何作用;出問題就有作用了,知道自己在哪裡操作錯誤了)
(1)知道怎麼用就可以了
#等級(level):
critical:50
error:40
warning:30
info:20
debug:10
二.今日內容大綱:
1.類的約束
2.MD5
3.異常處理
4.日誌
三.今日內容詳解:
1.類的約束
(1)第一種約束方式(因為書寫簡單,所以應用是最高的)
#專案經理 class Base:#第一種約束方式 #對子類進行了約束,必須重寫該方法 #以後上班了,看公司程式碼之後,只要發現了NoteImplementedError #繼承它,直接重寫它 def login(self): #如果,不重寫login,就會丟擲login的丟擲錯誤 #沒有被實現的錯誤 raiseNotImplementedError('你要重寫一下login這個方法,否則報錯!') #丟擲異常 #普通人員 class BaWu(Base): def login(self): print('吧務登陸') class Member(Base): def login(self): print('我是普通人登入') # class Houtai(Base): # def denglu(self): #報錯,上層程式設計師寫程式碼沒有按照規範來 # print('後臺登入') classHoutai(Base): def login(self): #報錯,上層程式設計師寫程式碼沒有按照規範來 print('後臺登入') #整合這些功能 def deng(obj): obj.login() m=Member() bw=BaWu() ht=Houtai() deng(m) deng(bw) deng(ht)
(2)
第二種約束方式
抽象類和抽象方法=>java C#
抽象方法不需要給出具體的方法體,抽象方法內只寫一個pass就可以了
在一個類中如果有一個方法是抽象方法,那麼這個類一定是一個抽象類
抽象類中,如果有抽象方法,此時這個類不能建立物件(只是個抽象的概念)
抽象方法不需要給出具體的方法體,抽象方法內只寫一個pass就可以了
概念:如果一個類中所有的方法都是抽象方法,這個類可以被稱為介面類
#寫一個抽象方法:匯入一個模組 from abc import ABCMeta,abstractmethod #此時抽象類不能建立物件 class Animal(metaclass=ABCMeta): #寫完這個東西,就是個抽象類 @abstractmethod #抽象方法 def chi(self): pass #吃應該只是一個抽象概念,沒辦法完美的描述出來吃什麼東西 #抽象類中可以有正常的方法 def dong(self): print('動物會動') # class Cat(Animal):#此時,貓類裡面也有一個抽象方法,此時的貓是建立不了物件的 # pass #想要實現,實現chi方法,具體看下面程式碼 class Cat(Animal): def chi(self): #重寫(覆蓋)父類中的抽象方法 print('貓喜歡吃魚') a=Cat() a.chi() a.dong()
2.MD5加密(加密的方法不止一種)
(1)MD5:加密,不可逆 //下面是最初版本//線上版本可以通過撞庫撞出來(md5線上破解)
#'哈哈哈哈'=>'dasdljaspfjsafp' import hashlib #首先,建立md5物件 obj=hashlib.md5() obj.update('alex'.encode('utf-8')) #這裡必須是位元組,把要加密的內容給md5 print(obj.hexdigest()) #拿到密文
(2)加鹽:撞庫幾乎是不可能的(注意:安全只是相對的)
import hashlib #首先,建立md5物件 obj=hashlib.md5(b'121231231232131242341531232') obj.update('alex'.encode('utf-8')) #把要加密的內容給md5 print(obj.hexdigest())
存資料一般是不存 明文的
應用: 銀行專案;密碼的儲存
uname upwd
alex 123(a82d88ed964485541be064d9d8a4d5a1)
(3)
import hashlib #首先,建立md5物件 obj=hashlib.md5(b'121231231232131242341531232') obj.update('123456'.encode('utf-8')) #把要加密的內容給md5 print(obj.hexdigest()) #應用 # 資料庫裡邊 #機器永遠不會出錯,出錯的只會是人 #huzixu
(4)
import hashlib #我自己的md5功能 def my_md5(s): obj = hashlib.md5(b'121231231232131242341531232') # obj.update('123456'.encode('utf-8')) # 把要加密的內容給md5 obj.update(s.encode('utf-8')) # 在這個地方犯了一個錯誤沒有把'密碼修改過來,注意s return obj.hexdigest() username='wusir' password='992578352d0a71554112c1bc2a31c5b5' # 登入 uname=input('請輸入你的使用者名稱') upwd=input('請輸入你的密碼') if uname==username and my_md5(upwd)==password: print('登入成功') else: print('登入失敗') #注意:MD5一定加鹽,不加鹽撞庫
3.異常處理
(1)
print(1/0) #報錯 print('冬瓜,你好') #沒處理上邊命令的錯誤,下面這條語句不會執行 #0不能作為除數,在程式執行的時候產生了一個錯誤物件, # 系統會丟擲這個錯誤,如果沒有人處理錯誤,錯誤就會被噴出給使用者
(2)
處理異常:在Python中,可以通過try...except...來處理錯誤 try: #類似於if...else print(1/0) except ZeroDivisionError: print('出錯了,出現了ZeroDivisionError') print('hahahhahahah') #處理錯誤之後,就可以正常運行了
(3)
# 所有的異常的根是Exception, 所有的異常類都會預設繼承Exception # 錯誤行為 # 打架錯誤 鬥毆 賭博 try: print(1/0) f=open('哈哈哈',mode='r') except Exception: #可以處理所有錯誤 print('出錯了') ''' 結果: 出錯了 ''' try: print(1/10) f=open('哈哈哈',mode='r') except Exception: #可以處理所有錯誤 print('出錯了') ''' 結果: 0.1 出錯了 '''
(4)
try: print(1/10) f=open('哈哈哈',mode='r') except ZeroDivisionError: #可以處理除數是0的錯誤 print('除以0出錯了') except FileNotFoundError: print('檔案不存在的錯誤')
(5)
try: print(1/10) except ZeroDivisionError: #可以處理除數是0的錯誤 print('除以0出錯了') except Exception: #兜底的處理錯誤 print('其他的錯誤') else: #當try中的程式碼不產生任何錯誤的時候,會自動的執行else裡的程式碼 pass finally: #最終,不管出錯還是不出錯,都要執行最後的finally #一般用來收尾的 print('嘻嘻嘻嘻嘻嘻') #很多人忘記關閉資料庫(十個人可能有九個人出錯),出現問題,所以,我們要注意
(6)
#如何手動丟擲異常,也就是,如何自己定義異常 def cul(a,b): #只能是數字相加 if(type(a)==int or type(a)==float)and (type(b)==int or type(b)==float): return a+b else: #丟擲異常 #raise 異常類(錯誤資訊) raise Exception('我沒辦法給你處理這樣的運算') # cul('寶寶','冬瓜') s=cul(1,2) print(s)
(7)
如何自己定義異常? class BaoBaoException(Exception): pass #BaoBaoException這個就是我們自己定義的異常 def cul(a,b): #只能是數字相加 if(type(a)==int or type(a)==float)and (type(b)==int or type(b)==float): return a+b else: #丟擲異常 #raise 異常類(錯誤資訊) raise BaoBaoException('我沒辦法給你處理這樣的運算') # cul('寶寶','冬瓜') s=cul(1,3) print(s)
(8)#練習
#寫一個男澡堂子 class GenderException(Exception): pass class Person: def __init__(self,name,gender): self.name=name self.gender=gender def xizao(self): print(f'{self.name}在洗澡') def nan_zao_tang_zi(ren): if ren.gender=='男': ren.xizao() else: raise GenderException('性別不對,去對門看看') #排除異常是很重要的 # (A) p1=Person('趙東瓜','不知道') p2=Person('樓西瓜','男') nan_zao_tang_zi(p2) # (B) try: p1=Person('趙冬瓜','不知道') p2=Person('樓西瓜','男') nan_zao_tang_zi(p1) nan_zao_tang_zi(p2) except GenderException: print('性別錯誤') #結果 #樓西瓜在洗澡 #性別錯誤
(9)
堆疊資訊,是看哪一行具體出現了問題;對我們找程式有作用
import traceback #用來檢視堆疊資訊 class GenderException(Exception): pass class Person: def __init__(self,name,gender): self.name=name self.gender=gender def xizao(self): print(f'{self.name}在洗澡') def nan_zao_tang_zi(ren): if ren.gender=='男': ren.xizao() else: raise GenderException('性別不對,去對門看看') # 拋異常是很重要的 try: p1=Person('趙冬瓜','不知道') p2=Person('樓西瓜','男') nan_zao_tang_zi(p1) nan_zao_tang_zi(p2) except GenderException: ret = traceback.format_exc() # 檢視堆疊資訊, 看錯誤的 print(ret) print('性別錯誤,很可惜') # 錯誤資訊叫做堆疊資訊 #使用者 ''' 堆疊資訊核心程式碼: import traceback #用來檢視堆疊資訊 ret = traceback.format_exc() # 檢視堆疊資訊, 看錯誤的 print(ret) #錯誤資訊: Traceback (most recent call last): File "F:/Python_workspace_S18/week4/day20 約束 異常處理 MD5 日誌處理/05 異常處理.py", line 150, in <module> nan_zao_tang_zi(p1) File "F:/Python_workspace_S18/week4/day20 約束 異常處理 MD5 日誌處理/05 異常處理.py", line 145, in nan_zao_tang_zi raise GenderException('性別不對,去對門看看') # 拋異常是很重要的 GenderException: 性別不對,去對門看看 性別錯誤,很可惜 ''' #產品上線就不會看到了,堆疊資訊是使用者應用時候產生的錯誤 #用的時候產生的錯誤,未來不是在這個地方看的
4.日誌
(1)
A.開發過程中,越全越好,知道發生了什麼
B.為了使用排錯,
C.我們可以自己定義等級 log第一個引數
D.規範一個專案組,用一套就行
一個專案組,分成三個小組(買車貸款,租車,資料處理)
交叉處理資料,如何把一個專案的日誌,寫到另一個專案組的日誌裡
(2)等級的講解1
#等級的講解 ///(小公司) import logging # 配置好日誌的處理, 預設就是GBK,通過pycharm轉換成GBK就正常了 logging.basicConfig(filename='x1.txt', # 把日誌資訊寫入的檔名 format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', # 時間的格式 level=10) # 當前配置表示 40及以上的分數會被寫入日件 #每個專案組可能會用一套這個樣子 # 向日志文件寫入內容 logging.critical("今天嫂子沒有來") # 50, 幾乎是最高的 logging.error("昨天嫂子來了") # 40 平時使用最多的就是他 logging.warn("氣死我了") # 30 警告 #這個已經去除了 logging.warning("還好吧") logging.info("提示") # 20 級 logging.debug("開發的時候把這個開著") # 10 logging.log(999, "寶寶今天有懵逼了") #自己定義的 ''' 結果: 2018-12-21 22:15:44 - root - CRITICAL -06 日誌: 今天嫂子沒有來 2018-12-21 22:15:44 - root - ERROR -06 日誌: 昨天嫂子來了 2018-12-21 22:15:44 - root - WARNING -06 日誌: 氣死我了 2018-12-21 22:15:44 - root - WARNING -06 日誌: 還好吧 2018-12-21 22:15:44 - root - INFO -06 日誌: 提示 2018-12-21 22:15:44 - root - DEBUG -06 日誌: 開發的時候把這個開著 2018-12-21 22:15:44 - root - Level 999 -06 日誌: 寶寶今天有懵逼了 '''
(3)交叉業務記錄:(大公司)
import logging # 建立一個操作日誌的物件logger(依賴FileHandler) file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8') # 建立檔案 file_handler.setFormatter(logging.Formatter( fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")) # 設定日誌檔案的格式 logger1 = logging.Logger('騰訊qq', level=10) # 建立一個日誌檔案處理物件 logger1.addHandler(file_handler) # 把檔案新增到日誌 logger1.error("麻花藤明天請大家吃飯. 去不去?") # 再建立⼀個操作⽇志的物件logger(依賴FileHandler) file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8') file_handler2.setFormatter(logging.Formatter( fmt="%(asctime)s - %(name)s -%(levelname)s -%(module)s: %(message)s")) logger2 = logging.Logger('百度貼吧', level=logging.DEBUG) logger2.addHandler(file_handler2) logger2.error("我才不去呢. 我們在北京. 離你那麼遠")
(4)澡堂子問題&logging問題
import logging import traceback # 建立一個操作日誌的物件logger(依賴FileHandler) file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8') # 建立檔案 file_handler.setFormatter(logging.Formatter( fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")) # 設定日誌檔案的格式 logger1 = logging.Logger('騰訊qq', level=10) # 建立一個日誌檔案處理物件 logger1.addHandler(file_handler) # 把檔案新增到日誌 logger1.error("麻花藤明天請大家吃飯. 去不去?") # 再建立⼀個操作⽇志的物件logger(依賴FileHandler) file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8') file_handler2.setFormatter(logging.Formatter( fmt="%(asctime)s - %(name)s -%(levelname)s -%(module)s: %(message)s")) logger2 = logging.Logger('百度貼吧', level=logging.DEBUG) logger2.addHandler(file_handler2) logger2.error("我才不去呢. 我們在北京. 離你那麼遠") class GenderException(Exception): pass class Person: def __init__(self, name, gender): self.name = name self.gender = gender #初始化也可以記錄 logger1.info(f"這個人的名字是{self.name}, 這個人的性別是:{self.gender}") def xizao(self): print(f"{self.name}在洗澡") class ZaoTang: def nan(self, ren): if ren.gender == "男": ren.xizao() else: raise GenderException("我這裡要的是男人") def nv(self, ren): if ren.gender == "女": ren.xizao() else: # logger1.error(traceback.format_exc()) #也可以在丟擲異常之前,記錄一個日誌 raise GenderException("我這裡要的是女人") # (A)#正常情況下 # p1 = Person("趙亞磊", "男") # p2 = Person("林志玲", "女") # zaotang=ZaoTang() # zaotang.nan(p1) # zaotang.nv(p2) # (B)寫錯的情況下 # p1 = Person("趙亞磊", "男") # p2 = Person("林志玲", "女") # zaotang=ZaoTang() # zaotang.nan(p1) # zaotang.nv(p2) # (C) try: p1 = Person("趙亞磊", "男") p2 = Person("林志玲", "女") zaotang = ZaoTang() zaotang.nan(p2) zaotang.nv(p1) except GenderException: print("走錯屋裡了") logger1.error('做錯屋裡了...') #寫入日誌,將走錯屋裡了 logger1.error(traceback.format_exc()) #將堆疊資訊記錄在日誌檔案中 #也就是在哪行裡出錯了