一丶約束 當我們編寫項目時會創建很多個類,來實現很多個功能,最後又需要把這些類都聯繫成一個,我們就需要來約束一下那些類中的方法,把需要聯繫的約束成一個方法. Email類繼承了BaseMessage,所以Email類中必須有send方法,否則就會報錯,我們用這樣的來約束類 編寫. 示例: class ...
一丶約束
當我們編寫項目時會創建很多個類,來實現很多個功能,最後又需要把這些類都聯繫成一個,我們就需要來約束一下那些類中的方法,把需要聯繫的約束成一個方法.
class BaseMessage(object): def send(self,x1): """ 必須繼承BaseMessage,然後其中必須編寫send方法。用於完成具體業務邏輯。 """ raise NotImplementedError(".send() 必須被重寫.") class Email(BaseMessage): def send(self,x1): """ 必須繼承BaseMessage,然後其中必須編寫send方法。用於完成具體業務邏輯。 """ pass obj = Email() obj.send(1)
Email類繼承了BaseMessage,所以Email類中必須有send方法,否則就會報錯,我們用這樣的來約束類 編寫.
示例:
class BaseMessage(object): def send(self): """ 必須繼承BaseMessage,然後其中必須編寫send方法。用於完成具體業務邏輯。 """ raise Exception() class Email(BaseMessage): def send(self): pass # 發送郵件 def f1(self): pass def f2(self): pass class Wechat(BaseMessage): def send(self): pass # 發送微信 def f1(self): pass def f2(self): pass class Msg(BaseMessage): def send(self): pass # 發送簡訊 def f1(self): pass def f2(self): pass def func(arg): """ 報警通知的功能 """ arg.send() obj = Msg() func(obj)示例
抽象類和抽象方法約束:
from abc import ABCMeta,abstractmethod class Base(metaclass=ABCMeta): # 抽象類 def f1(self): print(123) @abstractmethod def f2(self): # 抽象方法 pass class Foo(Base): def f2(self): print(666) obj = Foo() obj.f1()
其它語言中的介面:
介面,介面中不允許在方法內部寫代碼,只能約束繼承它的類必須實現介面中定義的所有方法。
偽代碼: interface IFoo: def f1(self,x1):pass def f2(self,x1):pass interface IBar: def f3(self,x1):pass def f4(self,x1):pass class Foo(IFoo,IBar):# 實現了2個介面 def f1(self,x1):pass def f2(self,x1):pass def f3(self,x1):pass def f4(self,x1):pass
總結:
1.什麼是介面以及其作用?
介面是一種數據類型,主要用於約束派生類中必須實現指定的方法.
python中不存在,Java和C#中是存在的
2.Python中使用過什麼來約束呢?
抽象類+抽象方法,在編寫上會很麻煩.
人為主動拋出異常
3.約束時,拋出的異常是否可以用其它的?
不專業: raise Exception(".send() 必須被重寫.")
專業:raise NotImplementedError(".send() 必須被重寫.")
應用場景:
多個類,內部都必須有某些方法時,需要使用基類+異常進行約束
二丶自定義異常
有時我們需要使程式跟我們預定的流程走時,我們可以自定義異常來約束它.
# 知識點:如何自定義異常類? class MyException(Exception): def __init__(self,code,msg): self.code = code self.msg = msg try: # 知識點:主動拋出異常 raise MyException(1000,'操作異常') except KeyError as obj: print(obj,1111) except MyException as obj: # 知識點:捕獲異常 print(obj,2222) except Exception as obj: print(obj,3333)
三丶加密
以前我們編寫註冊程式時,都是以明文的方式將密碼寫入文檔的,這樣很不安全,一旦文檔被盜取,將會發生不可估量的損失.我們就需要將密碼存儲時進行加密,然後將密文存入文檔,因為密文是無法被反解的,這樣當被人拿到文檔中的密文時也無法破解我們用戶的真正的密碼信息.
import hashlib def md5(pwd): # 實例化對象 obj = hashlib.md5() # 寫入要加密的位元組 obj.update(pwd.encode('utf-8')) # 獲取密文 return obj.hexdigest() user = input("請輸入用戶名:") pwd = input("請輸入密碼:") print(md5(pwd)) #21232f297a57a5a743894a0e4a801fc3
我們編寫登錄程式時又需要把密碼從文檔中拿出來,但是拿到的是密文,密文又沒法反解,我們應該怎麼驗證用戶的密碼呢?我們可以把用戶輸入的密碼用同樣的方式加密一遍,然後把加密的密碼跟從文檔讀出來的密碼密文比較,相等時登陸成功
import hashlib def md5(pwd): # 實例化對象 obj = hashlib.md5() # 寫入要加密的位元組 obj.update(pwd.encode('utf-8')) # 獲取密文 return obj.hexdigest() user = input("請輸入用戶名:") pwd = input("請輸入密碼:") if user == 'oldboy' and md5(pwd) == '21232f297a57a5a743894a0e4a801fc3': print('登錄成功') else: print('登錄失敗')
密碼加密後雖然說是無法反解的,那為什麼有人能破解呢?其實他們用大量欄位段加密後的密文來跟我們的密文把比較來獲取加密前的內容,我們可以防止這樣的事情發生,可以在密碼加密時再加嚴一層.
SALT = b'2erer3asdfwerxdf34sdfsdfs90' import hashlib def md5(pwd): # 實例化對象 obj = hashlib.md5(SALT) # 寫入要加密的位元組 obj.update(pwd.encode('utf-8')) # 獲取密文 return obj.hexdigest() user = input("請輸入用戶名:") pwd = input("請輸入密碼:") #21232f297a57a5a743894a0e4a801fc3 if user == 'oldboy' and md5(pwd) == 'c5395258d82599e5f1bec3be1e4dea4a': print('登錄成功') else: print('登錄失敗')
這樣,同樣的密碼,但是加密後的結果不一樣,那些人是無法通過撞庫撞出來真正的密碼的,密碼的安全性就會大大提高
四丶日誌
當我們程式推廣給用戶時,用戶並不知道我們程式應該遵循怎樣的運行規則,就有很大的幾率產生錯誤信息,當他們向我們反饋時,我們又不知道哪裡錯了,這裡就需要一個日誌文件來把用戶的錯誤都記錄下來,方便我們知道哪裡錯了.
import logging logger = logging.basicConfig(filename='rizhi.txt', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=30) #level 將大於等於30的錯誤級別寫入日誌中 logging.debug('x1') # 10 logging.info('x2') # 20 logging.warning('x3') # 30 logging.error('x4') # 40 logging.critical('x5') # 50 logging.log(10,'x6')
如何將錯誤信息具體到哪一行來寫到日誌中呢?
import logging logger = logging.basicConfig(filename='rizhi.txt', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=30) import traceback def func(): try: a = a +1 except Exception as e: # 獲取當前錯誤的堆棧信息 msg = traceback.format_exc() logging.error(msg) func()
當我們要將不同的錯誤信息寫入不同的文件中呢?
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('s1', level=logging.ERROR) logger1.addHandler(file_handler) logger1.error('123123123') # 在創建一個操作日誌的對象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('s2', level=logging.ERROR) logger2.addHandler(file_handler2) logger2.error('666')