約束 加密 日誌模塊
一 討論一下約束
python 中使用什麽來約束呢?
-抽象類 +抽象方法 特點編寫上麻煩
-人為主動拋出 實例如下
class BaseMessage(object): #約束繼承他的派生類必須實現其中指定的方法 def send(self,x1): """ 必須繼承BaseMessage,然後其中必須編寫send方法。用於完成具體業務邏輯。 """raise NotImplementedError(".send() 必須被重寫.") #用:raise Exception(".send() 必須被重寫.") 不專業
class Email(BaseMessage): def send(self,x1): """ 必須繼承BaseMessage,然後其中必須編寫send方法。用於完成具體業務邏輯。 """ pass
python抽象類加抽象方法的實例如下
from abc import ABCMeta,abstractmethod class Base(metaclass=ABCMeta): # 抽象類 deff1(self): #裏面可以包含普通方法 print(123) @abstractmethod def f2(self): # 抽象方法 pass class Foo(Base): # 子類中必須含有父類中的抽象方法 def f2(self): print(666) obj = Foo() obj.f1()
再多說一句,python 很少用抽象類加抽象方法的來做約束,比較麻煩.抽象類有兩個作用,不但能夠提供給子類提供公共的方法和變量使用,還可以約束派生類.
不行得再多說一句哈哈:Java中是怎麽約束的呢?Java中也有兩種方法 接口
接口只能用來做約束,功能單一.舉個例子如下看看吧(看之前要知道java是編譯型語言)
#接口,接口中不允許在方法內部寫代碼,只能約束繼承它的類必須實現接口中定義的所有方法。 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
來來就上面看到的來總結一下 接口的定義怎樣描述更加準確吧
接口是一種數據類型,主要用於約束派生類中必須實現指定的方法,只有java c#中存在
二 討論下自定義異常
先說下 主動拋出異常 raise Kryerror("隨便寫點原因")
難以描述先看個例子吧
class MyException(Exception): #自定義異常 像以前見到的keyerror,nameerror都是類 def __init__(self,code,msg):#且一定要繼承Exception 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:#Exception 是老大要寫在最後,最後出手 print(obj,3333)
上面這個例子理解了是吧,那要把下面這個例子搞明白
import os class ExistsError(Exception): #此處定義異常 pass class KeyInvalidError(Exception): #定義異常 pass def new_func(path,prev): """ 去path路徑的文件中,找到前綴為prev的一行數據,獲取數據並返回給調用者。 1000,成功 1001,文件不存在 1002,關鍵字為空 1003,未知錯誤 ... :return: """ response = {‘code‘:1000,‘data‘:None} try: if not os.path.exists(path): #巧妙用到not raise ExistsError() if not prev: raise KeyInvalidError() pass except ExistsError as e: #捕捉異常 response[‘code‘] = 1001 response[‘data‘] = ‘文件不存在‘ except KeyInvalidError as e: response[‘code‘] = 1002 response[‘data‘] = ‘關鍵字為空‘ except Exception as e: response[‘code‘] = 1003 response[‘data‘] = ‘未知錯誤‘ return response #下面用的是本方法,強烈推薦上面的方法,因為因為可以是業務邏輯簡單化 def func(path,prev): """ 去path路徑的文件中,找到前綴為prev的一行數據,獲取數據並返回給調用者。 1000,成功 1001,文件不存在 1002,關鍵字為空 1003,未知錯誤 ... :return: """ response = {‘code‘:1000,‘data‘:None} try: if not os.path.exists(path): response[‘code‘] = 1001 response[‘data‘] = ‘文件不存在‘ return response if not prev: response[‘code‘] = 1002 response[‘data‘] = ‘關鍵字為空‘ return response pass except Exception as e: response[‘code‘] = 1003 response[‘data‘] = ‘未知錯誤‘ return response def show(): return 8 def run():
run()
加個塞
如何獲取錯誤的堆棧信息
import traceback def func(): try: a = a +1 except Exception as e: # 獲取當前錯誤的堆棧信息 msg = traceback.format_exc() return msg print(func()) #
File "C:/Users/Administrator/AppData/Local/Temp/HZ$D.280.1227/HZ$D.280.1235/day26/10.日誌.py", line 33, in func
a = a +1
UnboundLocalError: local variable ‘a‘ referenced before assignment
三 討論下加密
說加密肯定要提 hashlib (哈希)模塊
先舉個實例把\吧
import hashlib #將哈希模塊導入 SALT = b‘2erer3asdfwerxdf34sdfsdfs90‘ #字節類型 def md5(pwd): #md5()函數就是用來加密的
# 實例化對象 obj = hashlib.md5(SALT) # 寫入要加密的字節 obj.update(pwd.encode(‘utf-8‘)) #pwd是要加密的字節 # 獲取密文 return obj.hexdigest() # 21232f297a57a5a743894a0e4a801fc3 # 66fbdc0f98f68d69cd458b0cee975fe3 # c5395258d82599e5f1bec3be1e4dea4a user = input("請輸入用戶名:") pwd = input("請輸入密碼:") #下面是已經加密過的密碼與用戶登錄密碼比對.用密文進行比對 if user == ‘oldboy‘ and md5(pwd) == ‘c5395258d82599e5f1bec3be1e4dea4a‘: print(‘登錄成功‘) else: print(‘登錄失敗‘)
下面是獲取一個密碼的密文
import hashlib
salt = b‘ui89‘
def md5(pwd):
obj = hashlib.md5(salt)
obj.update(pwd.encode("utf-8"))
return obj.hexdigest()
print(md5("mimi")) #沒加鹽之前dde6ecd6406700aa000b213c843a3091 加鹽之後301af0cfd0c10971d6375b21847e0e9b
四 討論日誌
import logging logger = logging.basicConfig(filename=‘xxxxxxx.txt‘, format=‘%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s‘, datefmt=‘%Y-%m-%d %H:%M:%S‘, 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 traceback def func(): try: a = a +1 except Exception as e: # 獲取當前錯誤的堆棧信息 msg = traceback.format_exc() logging.error(msg) func()
import logging logger1 = logging.basicConfig(filename=‘x1.txt‘, format=‘%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s‘, datefmt=‘%Y-%m-%d %H:%M:%S‘, level=30) logger2 = logging.basicConfig(filename=‘x2.txt‘, format=‘%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s‘, datefmt=‘%Y-%m-%d %H:%M:%S‘, level=30) logging.error(‘x4‘) #即使你定義了兩個日誌,所有的錯誤還會寫到第一個日至中 logging.error(‘x5‘)
怎樣可以自由發揮想寫那個日誌就寫那個日誌呢 那就自定義日誌了.
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‘)
約束 加密 日誌模塊