python之路-day19-面向对象之约束
生活随笔
收集整理的這篇文章主要介紹了
python之路-day19-面向对象之约束
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、上次內容回顧
?
1、反射
1、hasattr(對象,屬性(字符串))
2、getattr(對象,屬性(字符串))
3、setattr(對象,屬性,值)
4、delattr(對象,屬性)
?
2、issubclass ,type , isinstance
issunclass,判斷xxx對象或者類是否是xxx的子類
type:獲取xxx對象的數據類型
isinstance:判斷xxx對象是否是xxx類型(向上查找)
?
3、方法和
類外面寫的函數都是函數
在類中:
實例方法:
1、類名.方法() 函數
2、對象.方法() 方法
類方法:
都是方法
靜態方法
都是函數
4、md5
特點:不可逆
加鹽
import hashlib
obj = hashlib.md5(鹽)
obj.update(byte類型的明文)
result = obj.hetdidest()
?
二、類的約束類的約束,主要是為了定義一個父類,約束下面子類必須按照規則
完成父類中的功能(父類中的功能為空白)
在python中有兩種辦法來解決這樣的問題
1、提取父類。然后再父類中定義好方法。在這個方法中什么都不用干,拋一個異常
就可以了。這樣所有的子類都必須重寫這個方法。否則,訪問的時候報錯
2、使用元類來描述父類。在元類中給出一個抽象方法。這樣子類就不得不給出抽象方法
的具體實現。也可以起到約束的效果
第一套方案示例:
class Base:def login(self):raise Exception("你沒有實現login?法()") class Normal(Base):def login(self):pass class Member(Base):def denglu(self):pass class Admin(Base):def login(self):pass # 項?經理寫的總?? def login(obj):print("準備驗證碼.......")obj.login()print("進?主?.......") n = Normal() m = Member() a = Admin() login(n) login(m) # 報錯. login(a)
?
在執行到login(m)那一步程序報錯,原因是該類沒有login方法,導致去訪問父類的login方法,拋出異常報錯
Exception異常,是所有異常的根。我們無法通過這個異常來判斷出程序
是因為什么報的錯。所以,最好是換一個比較專業的錯誤信息,換成NotlmplementError
意為:沒實現的錯誤 ? 第二套方案:寫抽象類和抽象方法
from abc import ABCMeta, abstractmethod # 類中包含了抽象?法. 那此時這個類就是個抽象類. 注意: 抽象類可以有普通?法 class IGame(metaclass=ABCMeta):# ?個游戲到底怎么玩?? 你能形容? 流程能?樣么? @abstractmethoddef play(self):passdef turn_off(self):print("破B游戲不玩了, 脫坑了") class DNFGame(IGame):# ?類必須實現?類中的抽象?法. 否則?類也是抽象類def play(self):print("dnf的玩?法") # g = IGame() # 抽象類不能創建對象 dg = DNFGame() dg.play()通過代碼我們能發現. 這?的IGame對DNFGame進?了約束. 換句話說. ?類對?類進?了約束.接下來. 繼續解決我們?開始的問題.from abc import ABCMeta, abstractmethod class Base(metaclass=ABCMeta):@abstractmethoddef login(self):pass class Normal(Base):def login(self):pass class Member(Base):def denglu(self): # 這個就沒?了passdef login(self): # ?類對?類進?實現pass class Admin(Base):def login(self):pass # 項?經理寫的總?? def login(obj):print("準備驗證碼.......")obj.login()print("進?主?.......")n = Normal() m = Member() a = Admin() login(n) login(m) login(a)
?
?
總結: 約束. 其實就是?類對?類進?約束. ?類必須要寫xxx?法. 在python中約束的?式和?法有兩種:
1. 使?抽象類和抽象?法, 由于該?案來源是java和c#. 所以使?頻率還是很少的
2. 使??為拋出異常的?案. 并且盡量拋出的是NotImplementError. 這樣比較專
業, ?且錯誤比較明確.(推薦) ? ? 三、異常處理
上來先制造個異常:
def chu(a, b):return a/b ret = chu(10, 0) print(ret)結果: Traceback (most recent call last):File "/Users/sylar/PycharmProjects/oldboy/?向對象/day05.py", line 100, in <module>ret = chu(10, 0)File "/Users/sylar/PycharmProjects/oldboy/?向對象/day05.py", line 98, in chureturn a/b ZeroDivisionError: division by zero什么錯誤呢. 除法中除數不能是0. 那如果真的出了這個錯. 你把這?堆信息拋給客戶么? 肯定不能. 那如何處理呢?def chu(a, b):return a/b try:ret = chu(10, 0)print(ret) except Exception as e:print("除數不能是0")結果: 除數不能是0 那try...except是什么意思呢? 嘗試著運?xxxxx代碼. 出現了錯誤. 就執?except后?的
代碼. 在這個過程中. 當代碼出現錯誤的時候. 系統會產??個異常對象. 然后這個異常會向
外拋. 被except攔截. 并把接收到的異常對象賦值給e. 那這?的e就是異常對象. 那這?的
Exception是什么? Exception是所有異常的基類, 也就是異常的跟. 換句話說. 所有的錯誤都
是Exception的?類對象. 我們看到的ZeroDivisionError 其實就是Exception的?類. 那這樣
寫好像有點?問題撒. Exception表示所有的錯誤. 太籠統了. 所有的錯誤都會被認為是Exception.
當程序中出現多種錯誤的時候, 就不好分類了, 最好是出什么異常就?什么來處理. 這樣就更加合理了.
所以在try...execpt語句中. 還可以寫更多的except import traceback # 計算a+b def cul(a, b):if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):return a + belse:# 在這里有兩種方案. 1. 直接返回 , 2. 拋出異常# raise 拋出 Exception 錯誤和異常,所有錯誤的根raise Exception("我要的不是這個. 你應該我傳遞int或者float")try:print(cul(1, "胡辣湯")) # 加上異常的處理 except Exception as e:# 獲取到錯誤信息. 我們需要訪問堆棧信息print(traceback.format_exc()) # 獲取堆棧信息print("出現了錯誤")我們出現的錯誤. python中沒有給出具體的記錄, 慎用. 名字一定要符合規范 JackException 一個讓人無從得知的自定義異常,切記慎用自定義異常 自定義異常 class GenderException(Exception):passclass Person:def __init__(self, name, gender):self.name = nameself.gender = gender# 洗澡 -> 男的進男浴室def goto_nan_yushi(self):if self.gender != "男":raise GenderException("性別不對") # 除了名字以外都是父類中的Exceptionelse:print("歡迎光臨.") try:p2 = Person("wusir", "女")p2.goto_nan_yushi()p1 = Person("alex", "男")p1.goto_nan_yushi() except GenderException as e:print("你去男澡堂子干嘛?") except Exception as e:print("其他錯誤")
?
? 四、日志處理import logging # filename: ?件名 # format: 數據的格式化輸出. 最終在?志?件中的樣? # 時間-名稱-級別-模塊: 錯誤信息 # datefmt: 時間的格式 # level: 錯誤的級別權重, 當錯誤的級別權重?于等于leval的時候才會寫??件 logging.basicConfig(filename='x1.log',format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',datefmt='%Y-%m-%d %H:%M:%S', level=30) # 當前配置表示 0以上的分數會被寫??件 # CRITICAL = 50 # FATAL = CRITICAL # ERROR = 40 # WARNING = 30 # WARN = WARNING # INFO = 20 # DEBUG = 10 # NOTSET = 0 logging.critical("我是critical") # 50分. 最貴的 logging.error("我是error") # 40分 logging.warning("我是warning") logging.info("我是info") logging.debug("我是debug") logging.log(1, "我什么都不是")import traceback try:print(1/0) except Exception:logging.error(traceback.format_exc()) # 用法print("出錯了")import logging # 創建?個操作?志的對象logger(依賴FileHandler) # open() file_handler = logging.FileHandler('zuo.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=20) logger1.addHandler(file_handler) # 把文件助手和日志對象綁定 logger1.error('我是A系統出錯了') # 記錄日志# 再創建?個操作?志的對象logger(依賴FileHandler) file_handler2 = logging.FileHandler('you.log', 'a', encoding='utf-8') file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s -%(levelname)s -%(module)s: %(message)s")) logger2 = logging.Logger('B系統', level=20) logger2.addHandler(file_handler2)import traceback try:print(1/0) except Exception:logger2.critical(traceback.format_exc())print("出錯了. 請聯系管理員") print("程序繼續知悉個")from types import MethodType, FunctionType class Foo:@classmethoddef func1(self):pass@staticmethoddef func2(self):passdef func3(self):passdef func4(self):passobj = Foo() lst.append(obj.func4) for item in lst:print(isinstance(item, MethodType))
?
轉載于:https://www.cnblogs.com/alvin-jie/p/9948762.html
總結
以上是生活随笔為你收集整理的python之路-day19-面向对象之约束的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二分查找算法为什么要先排序
- 下一篇: Day10-Python3基础-协程、异