1. 程式人生 > >巨蟒python全棧開發-第20天 核能來襲-約束 異常處理 MD5 日誌處理

巨蟒python全棧開發-第20天 核能來襲-約束 異常處理 MD5 日誌處理

一.今日主要內容

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的丟擲錯誤
                #沒有被實現的錯誤
        raise
NotImplementedError('你要重寫一下login這個方法,否則報錯!') #丟擲異常 #普通人員 class BaWu(Base): def login(self): print('吧務登陸') class Member(Base): def login(self): print('我是普通人登入') # class Houtai(Base): # def denglu(self): #報錯,上層程式設計師寫程式碼沒有按照規範來 # print('後臺登入') class
Houtai(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())   #將堆疊資訊記錄在日誌檔案中
                                            #也就是在哪行裡出錯了