1. 程式人生 > 其它 >22.封裝 property裝飾器 介面 抽象類 鴨子型別

22.封裝 property裝飾器 介面 抽象類 鴨子型別

22.封裝 property裝飾器 介面 抽象類 鴨子型別

1.封裝

2.好處

3.語法

4.原理

5.訪問私有屬性的方法     property裝飾器

6.計算屬性

7.介面

8.抽象類

9.鴨子型別


1.封裝:
    什麼是封裝,就是將複雜的醜陋的,隱私的細節隱藏到內部,對外提供簡單的使用介面

    對外隱藏內部實現細節,並提供訪問的介面

    為什麼要封裝?
        兩個目的:
            1.為了保證 關鍵資料的安全性
            2.對外部隱藏實現細節,隔離複雜度

    什麼時候應該封裝?
        當有些資料不希望外界可以直接修改時,
        當有一些函式不希望給外界使用時

    如何使用 ?  
__封裝物件 - 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.setter
4.property裝飾器.py 5.封裝實現的原理 就是在載入類的時候 ,把__替換成 _類名__ Python 一般 不會強制 要求程式必須 怎麼怎麼的 封裝 對外部隱藏內部實現的細節,並提供訪問的介面 好處: 1.提高安全性 2.隔離複雜度 語法:將要封裝的屬性或方法名稱前加上雙下劃線 訪問被隱藏的屬性: ​ 提供用於訪問和修改的方法 使用property裝飾器可以將一個方法偽裝成普通順屬性,報紙屬性之間呼叫方法一致 封裝的實現原理 ,替換變數名稱 6.property 可以用來實現計算屬性 計算屬性指的是:屬性的值,不能直接獲得,必須通過計算才能獲取 例如:正方形求面積 6.計算屬性.py 7.介面 介面是一組功能的集合體,但是介面中僅僅包含功能的名字,不包含具體的實現程式碼 介面的本質:一套協議標準,遵循這個標準的物件就可以被呼叫 介面的目的: 就是為了提高擴充套件性 例: 7.介面的使用.py 在上述案例中,PC的程式碼一旦完成,後期無論什麼樣的裝置 只要遵循了USB介面協議,都能夠被電腦所呼叫 介面主要是方便了物件的使用者,降低使用者的 學習難度,只要學習一套使用方法,就可以以不變應萬變 問題: 如果子類沒有按照你的協議來設計,也沒辦法限制他,將導致程式碼無法執行 8.抽象類 指的是包含抽象方法(沒有函式體的方法)的類, 作用:可以限制子類必須類中定義的抽象方法 最後:python一般不會限制你必須怎麼寫,作為一個優秀的程式設計師,就應該自覺遵守相關協議 所以有了鴨子型別這麼一說: 如果這個物件長得像鴨子,走路像鴨子,那就他是鴨子 你只要保證你的類按照相關的協議類編寫,也可以達到提高擴充套件性的目的
22.封裝 property裝飾器 介面 抽象類 鴨子型別
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) # xx
4.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__key
5.封裝的實現原理.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.002623456790123457
6.計算屬性.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