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

一.今日主要內容java

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

二.今日內容大綱:python

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)spa

第二種約束方式

抽象類和抽象方法=>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())   #將堆棧信息記錄在日誌文件中
                                            #也就是在哪行裏出錯了

做業
2. 接口的做用? 
#約束和規範程序的書寫

接口是一種特殊的抽象類. 接口中全部的方法都是抽象方法.

"""
從java的角度看這個問題
java接口
(1)Java語言中存在的結構,有特定的語法和結構。
(2)Java語言中一個類所具備的方法的特徵集合,是一種邏輯上的抽象。

java接口做用:
(1)利於代碼的規範
這樣作的目的一方面是爲了給開發人員一個清晰的指示,告訴他們哪些業務須要實現;
同時也能防止因爲開發人員隨意命名而致使的命名不清晰和代碼混亂,影響開發效率。
(2)有利於對代碼進行維護
能夠一開始定義一個接口,把功能菜單放在接口裏,而後定義類時實現這個接口,
之後要換的話只不過是引用另外一個類而已,這樣就達到維護、拓展的方便性。
(3)保證代碼的安全和嚴密
一個好的程序必定符合高內聚低耦合的特徵,可以讓系統的功能較好地實現,
而不涉及任何具體的實現細節。這樣就比較安全、嚴密一些,這一思想通常在軟件開發中較爲常見。
"""
3.
抽象類和抽象方法的做用?
    抽象類爲了規範程序的書寫,抽象方法在子類繼承抽象方法
實現多態:
最簡單的一個做用,實現模板.
全部繼承抽象類的子類,必須強制實現抽象類的抽象方法.
若是沒有抽象方法,則子類可有,可沒有該方法.
定義一個抽象方法後,全部子類就必須實現了.

4. 抽象類加抽象方法 和 接口的區別?
(1)抽象類裏面能夠有非抽象方法,可是接口裏只能有抽象方法
他用於要建立一個體現某些基本行爲的類,併爲了該類聲明方法,
但並不能在該類中實現該類的狀況

(2)接口(Interface)是抽象類的變體.在接口中,全部方法都是抽象的.
多繼承可經過實現這樣的接口而得到.
接口中的全部方法都是抽象的,沒有一個有程序體.

網友回答:(java角度)
按三點答:
(1)先答屬性:抽象類能夠有普通成員變量,接口不行;
(2)而後答方法:抽象類有非抽象的方法和構造方法,而且修飾符能夠是私有的,接口只能是抽象的方法,而且修飾符是public,
(3)最後說一句只能繼承一個抽象類,但能實現多個接口。
 
 
5.python中應該如何約束派生類中指定的方法並編寫示例代碼?
方法一:
 
 
#項目經理
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)

 方法二:

#寫一個抽象方法:導入一個模塊
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()
6. 如何自定義異常? 
class BaoBaoException(Exception):
    pass
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)
7. md5加密是否能夠被反解? 
不能夠被反解,可是可能經過撞庫撞出來
'''
只是擴展:
MD5加密原理是散列算法,散列算法也稱哈希算法。
計算機專業學的數據結構就有哈希表這一知識點。
好比10除以3餘數爲一,4除以3餘數也爲一,但餘數爲一的就不知道這個數是哪一個了。
因此md5不能解密。
就算是設計這個加密算法的人都不知道。
可是你的密碼是怎麼驗證的呢?就是由於同一密碼加密後必定相同。
你輸入密碼加密後才能知道你的密碼是否正確。
也就是說,你的密碼只有你本身知道。
也是爲何扣扣密碼只能重置,不能找回的緣由。

MD5的算法是單向不可逆的
'''
8. 爲了防止撞庫,md5加密時須要作什麼操做並寫代碼實現。 
加鹽操做

import hashlib
obj=hashlib.md5(b"lierowier2849149&^&*(765)(*^&%^><>") #加的鹽,必須是bytes類型的
obj.update("密碼".encode("utf-8")) #密碼必須是bytes類型的
code=obj.hexdigest()
print(code)

9. 程序爲什麼要寫日誌?
記錄錯誤以及每一步執行了什麼,能夠方便操做錯誤,進行文件的從新處理

'''#爲了可以在程序在運行過程當中記錄錯誤,方便維護,和調試,減小維護成本爲何須要寫日誌首先咱們要樹立一個觀點,那就是「不是爲了記錄日誌而記錄日誌,日誌也不是隨意記的」。要實現可以只經過日誌文件還原整個程序執行的過程,達到能透明地看到程序裏執行狀況,每一個線程每一個過程到底執行到哪的目的。日誌就像飛機的黑匣子同樣,應當可以復原異常的整個現場乃至細節。做爲程序員,我相信吐槽寫註釋、寫文檔的段子已經見得不少了。然而在我看來,寫日誌的重要性徹底不亞於前二者,甚至在不少時候,比前二者更爲重要。'''#註釋//文檔//日誌
相關文章
相關標籤/搜索