python之路-day19-面向对象之约束
一、上次內(nèi)容回顧
?
1、反射
1、hasattr(對(duì)象,屬性(字符串))
2、getattr(對(duì)象,屬性(字符串))
3、setattr(對(duì)象,屬性,值)
4、delattr(對(duì)象,屬性)
?
2、issubclass ,type , isinstance
issunclass,判斷xxx對(duì)象或者類是否是xxx的子類
type:獲取xxx對(duì)象的數(shù)據(jù)類型
isinstance:判斷xxx對(duì)象是否是xxx類型(向上查找)
?
3、方法和
類外面寫的函數(shù)都是函數(shù)
在類中:
實(shí)例方法:
1、類名.方法() 函數(shù)
2、對(duì)象.方法() 方法
類方法:
都是方法
靜態(tài)方法
都是函數(shù)
4、md5
特點(diǎn):不可逆
加鹽
import hashlib
obj = hashlib.md5(鹽)
obj.update(byte類型的明文)
result = obj.hetdidest()
?
二、類的約束類的約束,主要是為了定義一個(gè)父類,約束下面子類必須按照規(guī)則
完成父類中的功能(父類中的功能為空白)
在python中有兩種辦法來解決這樣的問題
1、提取父類。然后再父類中定義好方法。在這個(gè)方法中什么都不用干,拋一個(gè)異常
就可以了。這樣所有的子類都必須重寫這個(gè)方法。否則,訪問的時(shí)候報(bào)錯(cuò)
2、使用元類來描述父類。在元類中給出一個(gè)抽象方法。這樣子類就不得不給出抽象方法
的具體實(shí)現(xiàn)。也可以起到約束的效果
第一套方案示例:
class Base:def login(self):raise Exception("你沒有實(shí)現(xiàn)login?法()") class Normal(Base):def login(self):pass class Member(Base):def denglu(self):pass class Admin(Base):def login(self):pass # 項(xiàng)?經(jīng)理寫的總?? def login(obj):print("準(zhǔn)備驗(yàn)證碼.......")obj.login()print("進(jìn)?主?.......") n = Normal() m = Member() a = Admin() login(n) login(m) # 報(bào)錯(cuò). login(a)
?
在執(zhí)行到login(m)那一步程序報(bào)錯(cuò),原因是該類沒有l(wèi)ogin方法,導(dǎo)致去訪問父類的login方法,拋出異常報(bào)錯(cuò)
Exception異常,是所有異常的根。我們無法通過這個(gè)異常來判斷出程序
是因?yàn)槭裁磮?bào)的錯(cuò)。所以,最好是換一個(gè)比較專業(yè)的錯(cuò)誤信息,換成NotlmplementError
意為:沒實(shí)現(xiàn)的錯(cuò)誤 ? 第二套方案:寫抽象類和抽象方法
from abc import ABCMeta, abstractmethod # 類中包含了抽象?法. 那此時(shí)這個(gè)類就是個(gè)抽象類. 注意: 抽象類可以有普通?法 class IGame(metaclass=ABCMeta):# ?個(gè)游戲到底怎么玩?? 你能形容? 流程能?樣么? @abstractmethoddef play(self):passdef turn_off(self):print("破B游戲不玩了, 脫坑了") class DNFGame(IGame):# ?類必須實(shí)現(xiàn)?類中的抽象?法. 否則?類也是抽象類def play(self):print("dnf的玩?法") # g = IGame() # 抽象類不能創(chuàng)建對(duì)象 dg = DNFGame() dg.play()通過代碼我們能發(fā)現(xiàn). 這?的IGame對(duì)DNFGame進(jìn)?了約束. 換句話說. ?類對(duì)?類進(jìn)?了約束.接下來. 繼續(xù)解決我們?開始的問題.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): # 這個(gè)就沒?了passdef login(self): # ?類對(duì)?類進(jìn)?實(shí)現(xiàn)pass class Admin(Base):def login(self):pass # 項(xiàng)?經(jīng)理寫的總?? def login(obj):print("準(zhǔn)備驗(yàn)證碼.......")obj.login()print("進(jìn)?主?.......")n = Normal() m = Member() a = Admin() login(n) login(m) login(a)
?
?
總結(jié): 約束. 其實(shí)就是?類對(duì)?類進(jìn)?約束. ?類必須要寫xxx?法. 在python中約束的?式和?法有兩種:
1. 使?抽象類和抽象?法, 由于該?案來源是java和c#. 所以使?頻率還是很少的
2. 使??為拋出異常的?案. 并且盡量拋出的是NotImplementError. 這樣比較專
業(yè), ?且錯(cuò)誤比較明確.(推薦) ? ? 三、異常處理
上來先制造個(gè)異常:
def chu(a, b):return a/b ret = chu(10, 0) print(ret)結(jié)果: Traceback (most recent call last):File "/Users/sylar/PycharmProjects/oldboy/?向?qū)ο?day05.py", line 100, in <module>ret = chu(10, 0)File "/Users/sylar/PycharmProjects/oldboy/?向?qū)ο?day05.py", line 98, in chureturn a/b ZeroDivisionError: division by zero什么錯(cuò)誤呢. 除法中除數(shù)不能是0. 那如果真的出了這個(gè)錯(cuò). 你把這?堆信息拋給客戶么? 肯定不能. 那如何處理呢?def chu(a, b):return a/b try:ret = chu(10, 0)print(ret) except Exception as e:print("除數(shù)不能是0")結(jié)果: 除數(shù)不能是0 那try...except是什么意思呢? 嘗試著運(yùn)?xxxxx代碼. 出現(xiàn)了錯(cuò)誤. 就執(zhí)?except后?的
代碼. 在這個(gè)過程中. 當(dāng)代碼出現(xiàn)錯(cuò)誤的時(shí)候. 系統(tǒng)會(huì)產(chǎn)??個(gè)異常對(duì)象. 然后這個(gè)異常會(huì)向
外拋. 被except攔截. 并把接收到的異常對(duì)象賦值給e. 那這?的e就是異常對(duì)象. 那這?的
Exception是什么? Exception是所有異常的基類, 也就是異常的跟. 換句話說. 所有的錯(cuò)誤都
是Exception的?類對(duì)象. 我們看到的ZeroDivisionError 其實(shí)就是Exception的?類. 那這樣
寫好像有點(diǎn)?問題撒. Exception表示所有的錯(cuò)誤. 太籠統(tǒng)了. 所有的錯(cuò)誤都會(huì)被認(rèn)為是Exception.
當(dāng)程序中出現(xiàn)多種錯(cuò)誤的時(shí)候, 就不好分類了, 最好是出什么異常就?什么來處理. 這樣就更加合理了.
所以在try...execpt語句中. 還可以寫更多的except import traceback # 計(jì)算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 錯(cuò)誤和異常,所有錯(cuò)誤的根raise Exception("我要的不是這個(gè). 你應(yīng)該我傳遞int或者float")try:print(cul(1, "胡辣湯")) # 加上異常的處理 except Exception as e:# 獲取到錯(cuò)誤信息. 我們需要訪問堆棧信息print(traceback.format_exc()) # 獲取堆棧信息print("出現(xiàn)了錯(cuò)誤")我們出現(xiàn)的錯(cuò)誤. python中沒有給出具體的記錄, 慎用. 名字一定要符合規(guī)范 JackException 一個(gè)讓人無從得知的自定義異常,切記慎用自定義異常 自定義異常 class GenderException(Exception):passclass Person:def __init__(self, name, gender):self.name = nameself.gender = gender# 洗澡 -> 男的進(jìn)男浴室def goto_nan_yushi(self):if self.gender != "男":raise GenderException("性別不對(duì)") # 除了名字以外都是父類中的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("其他錯(cuò)誤")
?
? 四、日志處理import logging # filename: ?件名 # format: 數(shù)據(jù)的格式化輸出. 最終在?志?件中的樣? # 時(shí)間-名稱-級(jí)別-模塊: 錯(cuò)誤信息 # datefmt: 時(shí)間的格式 # level: 錯(cuò)誤的級(jí)別權(quán)重, 當(dāng)錯(cuò)誤的級(jí)別權(quán)重?于等于leval的時(shí)候才會(huì)寫??件 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) # 當(dāng)前配置表示 0以上的分?jǐn)?shù)會(huì)被寫??件 # 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("出錯(cuò)了")import logging # 創(chuàng)建?個(gè)操作?志的對(duì)象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) # 把文件助手和日志對(duì)象綁定 logger1.error('我是A系統(tǒng)出錯(cuò)了') # 記錄日志# 再創(chuàng)建?個(gè)操作?志的對(duì)象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系統(tǒng)', level=20) logger2.addHandler(file_handler2)import traceback try:print(1/0) except Exception:logger2.critical(traceback.format_exc())print("出錯(cuò)了. 請(qǐng)聯(lián)系管理員") print("程序繼續(xù)知悉個(gè)")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))
?
轉(zhuǎn)載于:https://www.cnblogs.com/alvin-jie/p/9948762.html
總結(jié)
以上是生活随笔為你收集整理的python之路-day19-面向对象之约束的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二分查找算法为什么要先排序
- 下一篇: Maven安装与配置详解(Win10)