封裝 多態 經常使用內置函數 反射 動態導入模塊

封裝python

什麼是封裝 *****安全

封裝的好處 *****框架

property *****函數

什麼是封裝:對外部隱藏內部的屬性,以及實現細節,給外部提供使用的接口
         *封裝有隱藏的 意思,但不是單純的隱藏
封裝的目的:限制外部對內部數據的訪問
學習

py中 屬性的權限分爲兩種:  1.公開的:  沒有任何限制,誰都能訪問
                                              2.私有的:只有當前類自己可以訪問
this

         *默認爲公開的spa

爲何要封裝:1.提升安全性  =====>封裝屬性:當這個對象存在一個機密性的屬性。eg:  身份證 不該被外界直接訪問,那就封裝起來設計

          2.隔離複雜度=====>封裝方法:一個爲內部提供支持的方法,不該被外界直接訪問,那就封裝起來code

 

 

封裝屬性:

```python
class Student:

    def __init__(self,name,age,gender,id_card):
        self.name = name
        self.age = age
        self.gender = gender
        self.__id_card = id_card

    def show_id_card(self):
        # 能夠在這裏添加額外的任何邏輯代碼 來限制外部的訪問
        
        #在類的內部 能夠訪問
        print(self.__id_card)
```

對私有屬性的訪問以及修改

```python
class Student:
    def __init__(self,name,age,gender,id_card):
        self.name = name
        self.age = age
        self.gender = gender
        self.__id_card = id_card

    # 訪問被封裝的屬性  稱之爲訪問器
    def get_id_card(self,pwd):
        # 能夠在這裏添加額外的任何邏輯代碼 來限制外部的訪問
        # 在類的內部 能夠訪問
        if pwd =="123":
            return self.__id_card
        raise Exception("密碼錯誤!")


    # 修改被封裝的屬性   稱之爲設置器
    def set_id_crad(self,new_id):
        # 身份證必須是字符串類型
        # 長度必須是18位
        if isinstance(new_id,str) and len(new_id) == 18:
            self.__id_card = new_id
        else:
            raise Exception("身份證號碼 必須是字符串 且長度必須爲18!")
```

 

什麼樣的方法應該被封裝起來 :一個爲內部提供支持的方法,不該該讓外界直接訪問,就封裝起來

 

class ATM:

    def withdraw(self):
        self.__user_auth()
        self.__input_money()
        self.__save_record()
        # 輸入帳號和密碼
        # 顯示餘額
        # 輸入取款金額
        # 保存記錄

    def __user_auth(self):
        print("請輸入帳號密碼....")

    def __input_money(self):
        print("餘額爲100000000,請輸入取款金額!")

    def  __save_record(self):
        print("記錄流水....")

 

封裝的原理: py中是經過變形的方式來實現的對象

如何變形:在名稱帶有雙下劃線的變量名字前添加_類名    eg _Person__id_card

        經過變形後的名字能夠直接訪問被隱藏的屬性, 但不建議這麼作。變形僅在類的定義階段發生一次,後續再添加的帶有雙下劃線的任何屬性都不會變形,  就是普通屬性

封裝存在的問題:

property的做用 : 將一個方法假裝成普通屬性

why用property:是但願將訪問私有屬性和普通屬性的方式變得一致

setter: 用點語法 給屬性賦值時觸發

deleter:用點語法刪除屬性時觸發

 

eg:
class
Teacher: def __init__(self,name,age,salary): self.name = name self.age = age self.__salary = salary @property # getter # 用於訪問私有屬性的值 也能夠訪問普通屬性 def salary(self): return self.__salary @salary.setter # 用來設置私有屬性的值 也能夠設置普通屬性 def salary(self,new_salary): self.__salary = new_salary @salary.deleter # 用來設置私有屬性的值 也能夠刪除普通屬性 def salary(self): # print("can not delete salary!") del self.__dict__["_Teacher__salary"]

 

property的另外一種使用場景       

計算屬性:一個值它的屬性不是固定死的,而是經過計算動態產生的   eg: BMI

class Person:
    def __init__(self,name,height,weight):
        self.name = name
        self.height = height
        self.weight = weight
        # self.BMI = weight / (height ** 2)

    @property
    def BMI(self):
        return self.weight / (self.height ** 2)

    @BMI.setter
    def BMI(self,new_BMI):
        print("BMI 不支持自定義.....")


p = Person("egon",1.7,80)
print(p.BMI)
p.BMI = 10

多態

多態:不是一個具體的技術或代碼,而是指多個不一樣類型對象  能夠相應同一個方法,產生不一樣的結果

生活中能夠理解爲:某種事物具有多個不一樣形態   eg:水: 水的  固液氣 三態

多態帶來的好處:只要學習積累中的方法就行,不須要關心具體的哪一類實現的,  提升靈活性與擴展性

如何實現多態:鴨子類型

class Cat():
    def bark(self):
        print("喵喵喵")
    def run(self):
        print("四條腿跑!")
    def sleep(self):
        print("趴着睡!")
        
class Pig():
    def bark(self):
        print("哼哼哼!")
    def run(self):
        print("四條腿跑!")
    def sleep(self):
        print("側躺着睡!")

# 一個用來管理動物的方法   只要你傳入是一個動物 我就按照動物的標準來使用 徹底不用考慮你具體是什麼類型
def management_animal(animal):
    print("==================正在溜%s=============" % animal.__class__.__name__)
    animal.bark()
    animal.run()
    animal.sleep()

鴨子類型就是典型的多態,多種不一樣類型 ,使用方法同樣

經常使用的內置函數

 

__del__:當對象被刪除前會自動調用該方法

何時會刪除對象:i:程序運行結束,解釋器退出 將自動刪除全部數據,
          o:手動調用del   時也會刪除對象

* *該函數不是用來刪除對象的

使用場景:當你的對象在建立時,開啓了不屬於解釋器的資源,  eg: 打開一個文件
                 必須保證對象被剷除時 同時關閉額外的資源      eg:文件

它也被稱之爲析構函數   構造的  反義詞 ,      構造:是指從無到有           析 構:從有到無,簡單地說就是對象的全部數據所有刪除

__del__通常用於在對象刪除前 作一些清理操做

# 假設要求每個person對象都要綁定一個文件
class Person:
    def __init__(self,name,path,mode="rt",encoding="utf-8"):
        self.name = name
        self.file = open(path,mode,encoding=encoding)



    # 讀取數據的方法
    def read_data(self):
        return self.file.read()


    def __del__(self):
        print("del run!")
        self.file.close()


__str__:返回對象類型以及地址

在將對象轉爲字符串時執行

**返回值必須爲字符串類型,   子類能夠覆蓋該方法來完成對打印內容的自定義

 

class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    # 將對象轉換爲字符串時執行
    def __str__(self):
        print("str run")
        return "my name is %s , age is %s" % (self.name,self.age)


p = Person("rose",20)
# print(p) #在打印前都會現將要打印的內容轉爲字符串  經過調用__str__函數

str(p)

反射(檢討,自省)就是經過字符串來操做對象屬性

檢討:是指一個對象必須具有發現自身屬性,以及修改自身屬性的能力。

一個對象在設計初期,可能考慮不周全後期須要刪除或修改已經存在的屬性,和增長屬性

涉及到的方法:hasattr:判斷是否存在某個屬性
          getattr:獲取某個屬性的值

       setattr:新增或修改某個屬性
          delattr:刪除某個屬性

class MY_CMD:

    def dir(self):
        os.system("dir")

    def ipconfig(self):
        os.system("ipconfig")

cmd = MY_CMD()

while True:
    name = input("請輸入要執行的功能:")
    if hasattr(cmd,name):
        method = getattr(cmd,name)
        print(method)
        method()
    else:
        print("sorry this method is not exists....!")

動態導入模塊

靜態導入:直接寫import的douru 導入方式        前提:提早知道有這個模塊

動態導入:在須要的任什麼時候候    經過指定字符串類型的包名稱來導入須要的模塊

eg:

 

import importlib
mk = importlib.import_module(m_name)
mk 即導入成功的模塊

where:  經常使用在框架中,   由於框架設計者不可能提早知道後續須要的模塊何類

相關文章
相關標籤/搜索