生活随笔
收集整理的這篇文章主要介紹了
面向对象4
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
接口
- 接口:建立關聯的橋梁,方便管理代碼
- 接口類:用來定義功能的類,為繼承它的子類提供功能的,該類的功能方法一般不需要有實現體,實現體有繼承它的子類自己去實現
# 提供所有寵物應該有的功能
class PetInterface:def close_master(self):
pass# 提供所有看門應該有的功能
class WatchInterface:def watch_door(self):
pass# 沒有去繼承PetInterface,WatchInterface的Dog就是普通的Dog類
# 但繼承了PetInterface,該Dog就可以作為寵物狗,同理繼承WatchInterface就可以作為看門狗
class Dog(PetInterface, WatchInterface):def jiao(self):
passdef chi(self):
passdef pao(self):
pass# 一定要重寫接口的方法pass# 可以作為寵物及看門貓
class Cat(PetInterface, WatchInterface):
pass 抽象父類
- 抽象父類:擁有抽象方法(子類共有的方法,但是父類不能有具體的實現體)的父類
- 抽象方法:方法名是具體的,但是實現體是抽象的(在子類中重寫來具象化)
- 注意點:有抽象方法的父類不能被實例化(假設能被實例化,就可以調用自己的抽象方法,沒有任何意義)
# 實現抽象父類的語法
import abs
# abstract base class
class Sup(metaclass=
abc.ABCMeta):# 抽象父類中的抽象方法,在繼承它的子類中必須有自己的實現體# -- 抽象父類中的抽象方法實現體就沒有意義,實現與不實現都是pass填充
@abc.abstractmethoddef func(self):
passclass Sub(Sup):def func(self): # 必須重寫父類的抽象方法 import abc
class Quan(metaclass=
abc.ABCMeta):def __init__(self, name):self.name =
name# 共有方法,子類繼承就可以了def run(self):print(self.name +
'running')# 抽象方法:子類必須重寫
@abc.abstractmethoddef chi(self):
pass@abc.abstractmethoddef jiao(self):
passclass Dog(Quan):def kanmen(self):print(self.name +
'看門')def chi(self):super().chi()print(self.name +
'狗糧')def jiao(self):print(
'汪汪汪')class Wolf(Quan):def bulie(self):print(self.name +
'捕獵')def chi(self):print(self.name +
'肉')def jiao(self):print(
'嗷嗷嗷')dog = Dog(
'來福')
wolf = Wolf(
'呵呵')dog.jiao()
wolf.jiao()
dog.run()
wolf.run() 案例 了了解
# 抽象的類方法
import abs
class Sup(metaclass=
abc.ABCMeta):@classmethod@abc.abstractmethoddef func(cls):
passclass Sub(Sup):@classmethoddef func(self): # 必須重寫父類的抽象方法 多態
- 多態:對象的多種狀態 - 父類對象的多種(子類對象)狀態
import abc
class People(metaclass=
abc.ABCMeta):def __init__(self, name):self.name =
name@abc.abstractmethoddef speak(self):
passclass Chinese(People):def speak(self):print(
'說中國話')
class England(People):def speak(self):print(
'說英國話')if __name__ ==
'__main__':# 多態的體現:功能或是需求,需要父類的對象,可以傳入父類對象或任意子類對象# 注:一般都是規定需要父類對象,傳入子類對象def ask_someone(obj):print(
'讓%s上臺演講' % obj.name)
# 父類提供,自己直接繼承obj.speak()
# 父類提供,只不過子類重寫了
ch = Chinese(
'王大錘')en = England(
'Tom')# 傳入Chinese | England均可以,因為都是People的一種狀態(體現方式)
ask_someone(ch)ask_someone(en)# 傳入str不可以,因為str的對象沒有name和speak# s = str('白骨精')# ask_someone(s)# p = People('kkk') 鴨子類型
# 需求:需要一個對象,該對象有name屬性及speak方法,就可以作為一種狀態的體現被傳入
def ask_someone(obj):print(
'讓%s上臺演講' %
obj.name)obj.speak()# 鴨子類型:
# 1.先規定:有什么屬性及什么方法的類的類型叫鴨子類型
# 2.這些類實例化出的對象,都稱之為鴨子,都可以作為需求對象的一種具體體現
class A:# 能有自己特有的屬性和方法,可以和B完全不一樣,但是必須有鴨子類型規定的屬性和方法,不然就不是鴨子類型def __init__(self, name):self.name =
namedef speak(self): print(
'說AAAA')class B:# 能有自己特有的屬性和方法,可以和A完全不一樣,但是必須有鴨子類型規定的屬性和方法,不然就不是鴨子類型def __init__(self, name):self.name =
namedef speak(self): print(
'說BBBB')ask_someone(B('B'))
格式化方法與析構方法
class A:def __init__(self, name, age):self.name =
nameself.age =
age# 格式化方法:在外界打印該類對象是被調用# 格式化外界直接打印該類對象的字符串表示結果def __str__(self): # return 'abc' # 外界打印A類的對象,都打印 字符串 abc# return super().__str__() # 系統默認的在父類中返回的是對象存放的地址信息return '<name:%s | age:%s>' % (self.name, self.age)
# 根據對象實際的屬性格式化具體的輸出內容# 析構方法:在對象被消耗的那一剎那被調用,在被消耗前可以做一些事情def __del__(self):# del會在self代表的對象被消耗的時候被調用# 我們可以在析構函數中釋放該對象持有的其他資源,# 或者將一些持有資源持久化(保存到文件或數據庫中)del self.name
# 也可以將name存起來
a = A(
'老王', 88
)
print(a, type(a))import time
time.sleep(5
)print(
'文件馬上執行完畢,a就會被銷毀')
了解
class B:# 了解:對象.語法的內部實現def __setattr__(self, key, value):self.__dict__[key] = value
# 系統默認實現,在名稱空間添加名字# self.__dict__[key] = value.lower() # 可以自定義處理一些內容# 了了解:將對象添加屬性的方式可以同字典形式def __setitem__(self, key, value):self.__dict__[key] =
valueb =
B()
# 設置
b.name =
'BBB' # 內部走的是 __setattr__
b[
'age'] = 18
# 內部走的是 __setitem__# 訪問
print(b.name)
print(b.age)
反射
- 反射:通過字符串與類及類的對象的屬性(方法)建立關聯
class A:num = 10
print(hasattr(A,
'num'))
res = getattr(A,
'num',
'默認值')
print(res)
delattr(A, 'num')
print(setattr(A,
'tag', 10
))
# 類的屬性類來操作class B:def __init__(self, name):self.name =
name
print(hasattr(b,
'name'))
print(getattr(b,
'name',
'對象的屬性類不能獲取'))
delattr(b, 'name')
print(setattr(b,
'age', 18
))
# 對象的屬性對象來操作class C:def fn(self):print(
'fn')@classmethoddef func(cls):print(
'func')fn = getattr(C,
'fn')
c =
C()
fn(c) # 類獲取對象方法調用時傳入具體的對象
obj_fn = getattr(c,
'fn')
obj_fn() # 對象獲取對象方法調用時不用傳參
func = getattr(C,
'func')
func() # 類獲取類方法調用時不需要傳入參數 異常:程序運行時的錯誤
程序中的異常處理機制:
程序中的所有異常都會被處理程序中的所有異常都需要手動處理如果沒有手動處理異常,異常會交給Python解釋器處理 -- 處理的方式就是打印異常信息,并停止接收器
異常信息的三部分:
異常的追蹤信息:提示錯誤位置異常的類型:告知處理異常應該捕獲什么類型異常的內容:告知錯誤信息 處理異常的語法:
'''
try:# 會出現異常的代碼塊
except (異常類型1, 異常類型2) as 異常別名:# 異常處理邏輯
else:# 沒有出現異常會執行該分支
finally:# 無論是否出現異常都會執行該分支
''' 異常語法
-- 如果不出現異常,正常執行內部所有代碼
-- 如果出現異常會進入except分支
# part1
# 1.建議大家對異常處理時,一次只處理一個異常
try:print(asdsdsdsdsdsdsdsdsdsdsdsdsd)
# NameError
except NameError:
# except 后跟異常類型,如果不需要查看異常信息,可以省略異常信息print(
'出現了NameError異常')try:ls = [1, 2, 3, 4, 5
]print(ls[10])
# IndexError
except IndexError as e:
# 如果想知道異常信息,用別名接收print(
'出現了IndexError異常: %s' %
e)# part2
# 2.如果無法避免一句話或是一個完整的代碼結構會出現多個可能的異常,需要在一個try中提供多個except
# ls = [1, 2, 3, 4, 5]
ls = (1, 2, 3, 4, 5, 6
)
# try:
# print(ls[5]) # IndexError
# ls.append(10) # AttributeError
# except IndexError as e:
# print('出現了IndexError異常: %s' % e)
# except AttributeError as e:
# print('出現了AttributeError異常: %s' % e)
try:print(ls[5])
# IndexErrorls.append(10)
# AttributeError
except (AttributeError, IndexError) as e:print(
'出現了異常: %s' %
e)print(
'===============================')# part3
# 3.有些異常提前無法明確,或是壓根沒有明確的必要,可以捕獲異常的父類異常
ls = [1, 2, 3, 4, 5
]
# ls = (1, 2, 3, 4, 5, 6)
try:print(ls[5])
# IndexErrorls.append(10)
# AttributeError
except Exception as e:
# 可以通過多態的應用,捕獲父類,只要拋出的是該父類的子類異常,均可以被捕獲print(
'出現了異常: %s' %
e)# BaseException:所有異常的基類 | Exception:常規錯誤的基類# part4
# 4.了了解 - try語法的else分支:當try檢測的代碼塊沒有出現異常,才會走else分支
try:print(aaaa)
except Exception as e:print(
'出現了異常', e)
else:print(
'沒有異常')# part5
# 5.finally:無論是否出現異常都會執行該分支
try:f = open(
'1.txt',
'w', encoding=
'utf-8')f.write(b'123')
except Exception as e:print(
'出現了異常', e)
finally:print(
'無論是否出現異常都會執行該分支')f.close() # 文件只要打開,不管操作是否出現異常,都需要釋放文件資源 四種 自定義異常
- 自定義異常的目的:想拋一個有意義的異常,但這個異常系統沒有提供,自定義一個
class PeopleNameError(Exception):
# Exception | BaseException# pass# 可以通過__init__明確外界的錯誤信息接收給那個屬性# 再在__str__中格式化外界捕獲異常,打印異常信息的格式def __init__(self, msg):self.msg =
msgdef __str__(self):return 'PeopleNameError: ' +
self.msgdef get_name():name = input(
'name: ')if 'sb' in name.lower():raise PeopleNameError(
'人名不能有敏感詞匯')return nametry:print(get_name())
except PeopleNameError as e:print(e)
# PeopleNameError: 人名不能有敏感詞匯 斷言
num = int(input(
'num: '))
assert num < 0
# 斷言:只有滿足斷言條件,程序才能往下執行,反之拋出異常
print(abs(num))
?
轉載于:https://www.cnblogs.com/wangyisen/p/10864207.html
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的面向对象4的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。