-
封裝
-
接口
一、封裝
1、什么是封裝
封裝就是將復雜的丑陋的、隱私的細節隱藏到內部,對外提供簡單的使用接口的過程。
2、為社么要封裝
封裝有兩個目的:一是為了保證關鍵數據的安全性,而是為了對外部隱藏實現細節,隔離復雜度。
3、什么時候應該封裝
當有一些數據不希望外界可以直接修改或者有一些函數不希望給外界使用的時候,可以使用封裝。
4、封裝的使用
在需要封裝的屬性或者函數的名字前加雙下划線,如下實例:
class Person(object):
def __init__(self,id,name,age):
self.__id = id
self.name = name
self.age = age
def __address(self):
print("地址是。。。".self.name)
被封裝的屬性或者方法是不能直接獲取或者修改的,可以通過間接的方法獲取或者修改。
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
上例代碼中的封裝屬性buffer_size屬性是不可被外界直接獲取和修改的,但是將其放在一個可被調用的set_buffrt_size方法中,通過給改方法傳參達到修改buffer_size的目的,通過方法get_buffer_size達到獲取buffer_size的目的。
5、property裝飾器
在調用方法的時候需要加括號,調用屬性的時候不需要加括號,在不知道是方法還是屬性的情況下容易出現使用錯誤,不便於調用,為了讓兩種調用的形式保持一致,可以通過調用property裝飾器實現需求。
當調用的方法不用傳參數的時候:
class Downloader:
def __init__(self,filename,url,buffer_size):
self.filename = filename
self.url = url
self.__buffer_size= buffer_size
@proprety
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
@proprety
def get_buffer_size(self):
return self.__buffer_size
當被調用的方法中需要傳參時:
class Downloader:
def __init__(self,filename,url,buffer_size):
self.filename = filename
self.url = url
self.__buffer_size= buffer_size
@proprety
def start_download(self):
if self.__buffer_size <= 1024*1024:
print("開始下載....")
print("當前緩沖器小",self.__buffer_size)
else:
print("內存炸了! ")
@proprety
def set_buffer_size(self):
return self.__buffer_size
@set_buffer_size.setter
def set_buffer_size(self,size):
#可以在方法中添加額外的邏輯
if not type(size) == int:
print("大哥 緩沖區大小必須是整型")
else:
print("緩沖區大小修改成功!")
self.__buffer_size = size
@proprety
def get_buffer_size(self):
return self.__buffer_size
6、計算屬性
所謂計算屬性就是獲取自己屬性的值,並計算得到新的值賦值給另一個屬性,另一個屬性就叫做計算屬性。
當獲取的屬性的值改變時,計算屬性的值時不變的,此時可以通過定義一個方法,將計算的過程放入其中,可以解決計算屬性的值不變的過程。
class Squre(object):
def __init__(self,line):
self.line = line
self.s = self.line**2
s = Squre(3)
print(s.s) # 9
s.line = 4
print(s.s) # 9
# 解決辦法
class Squre(object):
def __init__(self,line):
self.line = line
@proprety
def s(self):
return self.line**2
s = Squre(3)
print(s.s) # 9
s.line = 4
print(s.s) # 16
二、接口
1、什么叫接口
接口是一組功能的集合,但是接口中僅包含功能的名字,不包含具體的實現代碼。接口本質是一套協議標准,遵循這個標准的對象就能被調用 。
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)
在上述案例中,PC的代碼一旦完成,后期無論什么樣的設備,只要遵循了USB接口協議,都能夠被電腦所調用。接口主要是方便了對象的使用者,降低使用者的 學習難度,只要學習一套使用方法,就可以以不變應萬變 。
2、python中的“接口”
在python中,追求的時不限制程序員取如何編寫代碼,所以並沒有接口這一說法。比如上述代碼中USB類可以不用寫,在寫鼠標和鍵盤的功能函數時,只要程序員遵守要求編寫代碼即可,在python中,一個程序員應該自覺遵守規則。
3、abc模塊的使用
抽象類:指的是包含抽象方法(沒有函數體的方法)的類,用來限制子類中必須定義的抽象方法。上述代碼中的USB類即為一個抽象類。
假如某個程序員不遵守抽象類中的抽象方法的定義,定義了其它的方法或者沒有定義某種方法,此時可以通過調用abc模塊進行限制,不按照規定的抽象方法定義就報錯。
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("runrunrurn...")
b = B()
上訴代碼中的B類沒有定義run1()方法,程序無法正常運行。