22.封裝 property裝飾器 介面 抽象類 鴨子型別
阿新 • • 發佈:2022-03-25
22.封裝 property裝飾器 介面 抽象類 鴨子型別
1.封裝 2.好處 3.語法 4.原理 5.訪問私有屬性的方法 property裝飾器 6.計算屬性 7.介面 8.抽象類 9.鴨子型別 1.封裝: 什麼是封裝,就是將複雜的醜陋的,隱私的細節隱藏到內部,對外提供簡單的使用介面 對外隱藏內部實現細節,並提供訪問的介面 為什麼要封裝? 兩個目的: 1.為了保證 關鍵資料的安全性 2.對外部隱藏實現細節,隔離複雜度 什麼時候應該封裝? 當有些資料不希望外界可以直接修改時, 當有一些函式不希望給外界使用時 如何使用 ?22.封裝 property裝飾器 介面 抽象類 鴨子型別__封裝物件 - 1.封裝的基本使用.py 被封裝內容的特點: 1.外部不能直接訪問 2.內部依然可以使用 學習了封裝後就可以控制屬性的許可權 在python只要兩種許可權, 1.公開的.預設就是公開的 2.私有的,只能由當前類自己使用 在外界訪問私有的內容 屬性雖然被封裝了,但是還是需要使用的,在外界如何訪問 通過定義方法類完成對私有屬性的修改和訪問 3.如何訪問被封裝的屬性.py ``` 這樣一來我們可以在外界修改這個關鍵資料時,做一些限制4.property裝飾器 通過方法來修改或訪問屬性,本身沒什麼問題,但是這給物件的使用者帶來了麻煩. 使用必須知道哪些是普通屬性,哪些是私有屬性,需要使用不同的方式來呼叫他們 property裝飾就是為了使得呼叫方式一致 property 三個相關裝飾器 1.property 該裝飾器用於獲取屬性的方法上 2[email protected] 該裝飾器用在修改屬性的方法上 3[email protected] 該裝飾器用於刪除屬性的方法上 ps: key 是被property 裝飾的方法名稱,也就是屬性的名稱 內部會建立一個物件,變數名稱就是函式名稱 所以在使用setter 和 deleter時,必須保證使用物件的名稱去呼叫方法. 所以是 key.setter4.property裝飾器.py 5.封裝實現的原理 就是在載入類的時候 ,把__替換成 _類名__ Python 一般 不會強制 要求程式必須 怎麼怎麼的 封裝 對外部隱藏內部實現的細節,並提供訪問的介面 好處: 1.提高安全性 2.隔離複雜度 語法:將要封裝的屬性或方法名稱前加上雙下劃線 訪問被隱藏的屬性: 提供用於訪問和修改的方法 使用property裝飾器可以將一個方法偽裝成普通順屬性,報紙屬性之間呼叫方法一致 封裝的實現原理 ,替換變數名稱 6.property 可以用來實現計算屬性 計算屬性指的是:屬性的值,不能直接獲得,必須通過計算才能獲取 例如:正方形求面積 6.計算屬性.py 7.介面 介面是一組功能的集合體,但是介面中僅僅包含功能的名字,不包含具體的實現程式碼 介面的本質:一套協議標準,遵循這個標準的物件就可以被呼叫 介面的目的: 就是為了提高擴充套件性 例: 7.介面的使用.py 在上述案例中,PC的程式碼一旦完成,後期無論什麼樣的裝置 只要遵循了USB介面協議,都能夠被電腦所呼叫 介面主要是方便了物件的使用者,降低使用者的 學習難度,只要學習一套使用方法,就可以以不變應萬變 問題: 如果子類沒有按照你的協議來設計,也沒辦法限制他,將導致程式碼無法執行 8.抽象類 指的是包含抽象方法(沒有函式體的方法)的類, 作用:可以限制子類必須類中定義的抽象方法 最後:python一般不會限制你必須怎麼寫,作為一個優秀的程式設計師,就應該自覺遵守相關協議 所以有了鴨子型別這麼一說: 如果這個物件長得像鴨子,走路像鴨子,那就他是鴨子 你只要保證你的類按照相關的協議類編寫,也可以達到提高擴充套件性的目的
class Person: def __init__(self,id_number,name,age): self.__id_number = id_number self.name = name self.age = age def show_id(self): print(self.__id_number) p = Person("111111111",'jack',29) p.__id_number = "222" # print(p.__id_number) print(p.show_id()) """ 111111111 None """1.封裝的基本使用.py
class PC: def __init__(self,price,kind,color): self.price = price self.kind = kind self.color = color def open(self): print("接通電源") self.__check_device() print("載入核心") self.__start_services() print("初始化核心") self.__login() print("啟動GUI") def __check_device(self): print("硬體檢測1") print("硬體檢測2") print("硬體檢測3") print("硬體檢測4") def __start_services(self): print("啟動服務1") print("啟動服務2") print("啟動服務3") print("啟動服務4") def __login(self): print("login....") print("login....") print("login....") pc1 = PC(20000,'蘋果',"紅色") pc1.open() # pc1.login() """ 接通電源 硬體檢測1 硬體檢測2 硬體檢測3 硬體檢測4 載入核心 啟動服務1 啟動服務2 啟動服務3 啟動服務4 初始化核心 login.... login.... login.... 啟動GUI """2.封裝方法.py
""" 這是一個下載器類,需要提供一個快取大小這樣的屬性 快取大小不能超過記憶體限制 """ class Downloader: def __init__(self,filename,url,buffer_size): self.filename = filename self.url = url self.__buffer_size = buffer_size def start_download(self): if self.__buffer_size <= 1024 * 1024: print("開始下載....") print("當前緩衝器大小",self.__buffer_size) else: print("記憶體炸了") def set_buffer_size(self,size): # 可以在方法中新增額外的邏輯 if not type(size) == int: print("大哥,緩衝區大小必須是整型") else: print("緩衝器大小修改成功") self.__buffer_size = size def get_buffer_size(self): return self.__buffer_size d = Downloader("葫蘆娃","http://www.baidu.com",1024*1024) # 通過函式去修改內部封裝的屬性 d.set_buffer_size(1024*512) # 通過函式訪問內部封裝的屬性 print(d.get_buffer_size()) print(d.filename) d.start_download() """ 緩衝器大小修改成功 524288 葫蘆娃 開始下載.... 當前緩衝器大小 524288 """3.如何訪問被封裝的屬性.py
class A: def __init__(self,name,key): self.__name = name self.__key = key @property def key(self): return self.__key @key.setter def key(self,new_key): if new_key <= 100: self.__key = new_key else: print("key 必須小於等於100") @key.deleter def key(self): print("不允許刪除該屬性") del self.__key # @property # def name(self): # return self.__name # # @name.setter # def name(self, new_name): # self.__name = new_name a = A('jack',123) # print(a.name) print(a.key) # 123 a.key = 321 # key 必須小於等於100 print(a.key) # 123 # del a.key # print(a.key) a.name = "xx" print(a.name) # xx4.property裝飾器.py
class A: def __init__(self,key): self.__key = key @property def key(self): return self.__key @key.deleter def key(self): del self.__key a = A("123") print(a.key) # 123 # del a.key # print(a.key) print(a._A__key)# 123 a.__name = 1 print(a.__dict__) # {'_A__key': '123', '__name': 1} print("__key".replace("__","_A__")) # _A__key5.封裝的實現原理.py
class Square: def __init__(self,width): self.width = width # self.area = self.width * self.width @property def area(self): return self.width * self.width s = Square(10) print(s.area) # # 練習: 定義一個類叫做person # 包含三個屬性 身高 體重 BMI # BMI的值需要通過計算得來 公式 體重 / 身高的平方 class Person: def __init__(self,high,wight): self.high = high self.wight = wight @property def BMI(self): return self.wight / (self.high ** 2) p = Person(180,85) print(p.BMI)# 0.0026234567901234576.計算屬性.py
class USB: def open(self): pass def close(self): pass def read(self): pass def write(self): pass class Mouse(USB): def open(self): print("滑鼠開機.....") def close(self): print("滑鼠關機了...") def read(self): print("獲取了游標位置....") def write(self): print("滑鼠不支援寫入....") def pc(usb_device): usb_device.open() usb_device.read() usb_device.write() usb_device.close() m = Mouse() # 將滑鼠傳給電腦 pc(m) class KeyBoard(USB): def open(self): print("鍵盤開機.....") def close(self): print("鍵盤關機了...") def read(self): print("獲取了按鍵字元....") def write(self): print("可以寫入燈光顏色....") # 來了一個鍵盤物件 k = KeyBoard() pc(k) class UDisk(USB): def open(self): print("U盤啟動了...") def close(self): print("U盤關閉了...") def read(self): print("讀出資料") def write(self): print("寫入資料") u = UDisk() pc(u)7.介面的使用.py
"""""" """ abc 不是隨意取的 而是單詞的縮寫 abstract class 翻譯為抽象類 抽象類的定義 : 類中包含 沒有函式體的方法 """ import abc class AClass(metaclass=abc.ABCMeta): @abc.abstractmethod def run(self): pass @abc.abstractmethod def run1(self): pass class B(AClass): def run(self): print("runnnnnnnn....") def run1(self): print("run111111") b = B() print(b.run) """ <bound method B.run of <__main__.B object at 0x0000025B2DB25438>> """8.abc模組的使用.py