Python 物件導向筆記

Dapeng_ai發表於2021-10-18

Python 物件導向課程筆記


前言

Python 物件導向


正文

基本概念

  • 什麼是物件:
    • 萬物皆物件
    • 物件是具體物體:
      • 擁有屬性
      • 擁有行為
      • 封裝零散為整體
    • OOP(Object Oriented Programming)物件導向程式設計:
      • python 中一切都是物件
  • 物件導向 or 程式導向:都是解決問題的思路
    • 程式導向:關注解決問題每一個過程
    • 物件導向:關注解決問題所需要的物件
  • 物件 抽象出 類; 類 例項化 物件。
  • 經典類 和 新式類:是(新)否(舊)繼承了 object
  • 物件導向的三大特性:
    • 封裝
    • 繼承
    • 多型

屬性

  • 屬性和變數的區別
    • 變數是可以改變的量值(存在不同訪問許可權)
    • 屬性表示物件的特性(只能通過物件訪問,物件通過變數引用,因此和變數一樣存在不同的訪問許可權)
  • 類屬性和物件屬性
    • 物件屬性:僅屬於物件
      • 檢視物件所有屬性obj.__dict__,返回字典。
      • 新增物件屬性obj.age = 18
      • 通過物件可以訪問到類屬性:查詢邏輯是優先查詢物件自身,如果沒找到則根據class找到物件對應的類,從類中尋找。
      • 通過物件只能訪問類屬性,而不能修改。
      • 只能刪除物件本身屬性(直系屬性)
    • 類屬性:屬於該類的所有物件
      • 類也是物件
      • 增改查刪
        • 查詢:和物件查詢一樣.__dict__
        • 刪除: del class_name.xxx
        • 類的屬性無法修改(只讀),物件的屬性可以直接修改
      • 類屬性被各物件所共享
  • __slots__ = ['xxx']:表示該類建立的物件只能新增指定('xxx')屬性

方法

  • 方法劃分:
    • 例項方法:類例項化出來的例項物件,預設第一個引數必須收到一個例項
    • 類方法:預設第一個引數必須收到一個類
    • 靜態方法:第一個引數不預設接收
    • 注意
      • 劃分依據是第方法第一個引數必須要接受的資料型別
  • 一個目標的行為動作
  • @classmethod 裝飾器,類方法
  • @staticmethod 靜態方法
  • 方法的使用:根據規則和呼叫,來針對不同的問題設計不同的方法
  • 裝飾器的作用:在保證原本函式不改變的前提下,直接給函式增加功能
  • 元類:類是由另外一個類所建立出來的,因此存在建立類物件的類。(type)
  • 因此可以用 type 來手動建立型別
  • 元類根據__metaclass__來指明
  • 可以通過.__base__檢視父類
class Person:
    __metaclass__ = xxx
  • 類的建立流程:
    • 檢測類物件是否有明確的mateclass屬性。
    • 檢測父類中是否存在mateclass屬性。
    • 檢測模組中是否存在mateclass屬性。
    • 通過內建的 type 這個元類來建立這個類物件。
  • 類的描述:方便合作開發(標準註釋)
    • 引數的含義和格式,方法作用,是否有預設值
  • 生成專案文件
    • 方法 1:內建模組 pydoc
      • python -m pydoc -w 模組名稱
    • 方法 2:第三方模組(Sphinx;epydoc;doxygen)
  • 私有化屬性(偽私有,python 沒有私有化):
    • x:共有
    • _x:受保護,類內部,子類內部,模組其他位置或者跨模組訪問會被 warm,跨模組時如果from xxx import *會失敗,本模組__all__ = ["xxx"]表示其他模組中可以匯入。
    • **x:受保護,只有類內部能用。但對於在類外的**\_效果一樣
    • 因為偽私有,還是可以強行訪問,比如xxx.__dict__
  • 私有化方法:和私有化屬性類似
  • __init__建立例項物件後自動呼叫該方法
  • 只讀屬性:
    • 方式 1:
      • 全部隱藏:私有化操作__
      • 部分公開:公開
    • 方式 2:可以以@property使用屬性的方式來使用該方法
      • 獲得使用@property,修改使用@xxx.setter,刪除使用@xxx.deleter
  • 經典類 和 新式類的區別:
    • 經典類中 property 只有讀取方法有效
  • setattr,通過例項.屬性 = v 時,會呼叫該方法、通過該方法 來判斷是否將屬性新增到dict字典
  • 內建特殊屬性:
    • 類屬性:
      • __dict__:類屬性
      • __bases__:類所有父類的元組
      • __doc__:類的文件字串
      • __name__:類名
      • __module__:類定義所在的模組
    • 例項屬性:
      • __dict__:例項的屬性
      • __class__:例項對應的類
  • 引數:*args,**kwargs
  • 內建特殊方法:
    • 生命週期方法:
    • others:
      • 資訊格式化:
        • __str__:print 當前類時,會直接呼叫`str也可以通過 str(例項)獲得.(面向使用者)
        • __repr__:str 的次選項,也可以通過 repr()直接呼叫或者直接輸出例項(互動環境)(面向開發)
      • 呼叫操作:__call__:讓例項具備被呼叫的能力
      • 索引操作:通過實現三個內建方法
        • __setitem__
        • __getitem__
        • __delitem__
      • 切片操作:python3 中統一由索引操作實現了
      • 比較大小:
        • 相等:__eq__ == or != ,也可以再寫__ne__針對不等單獨定義
        • 大於 gt
        • 大於等於 ge
        • 小於 lt
        • 小於等於 le
        • 對於相反操作,如果只定義了其中一個,直譯器會自動反向操作
        • @functools.total_ordering 會自動補全組合操作
        • 布林值:__bool__
      • 遍歷操作:
        • 實現 for in 遍歷:
          • __getitem__,記得設定停止條件 raise StopIteration("xxx")
          • __iter__,優先順序更高
          • __next__,變成迭代器,注意設定終止條件
          • 迭代器必須有 iter 和 next 方法,可迭代物件只需要實現 iter.可迭代物件一定可以通過 for in 訪問,但可以通過 for in 迭代不一定是可迭代物件.
          • 多次重複使用需要回退
      • 描述器:可以描述屬性操作的物件
        • __set__(self,instance,owner)
        • __get__(self,instance,value)
        • __delete__(self,instance)
        • 定義方式:
          • property
          • 先定義一個類,設定 get,set,delete.然後直接呼叫這個類(即描述器).呼叫是通過例項不是類呼叫.
        • 只實現了 get,就是非資料描述器,實現 get 和 set 是資料描述器.
        • 優先順序:資料描述器 > 例項屬性 > 非資料描述器
      • 使用類,實現裝飾器:
        • __init__接收並儲存 func,__call__使用 func

記憶體管理機制

  • python 的生命週期:
    • 監聽物件生命週期:會自動呼叫
      • __new__ 初始化建立
      • __del__ 釋放
      • __init__
    • id 函式獲得物件記憶體地址,hex 函式獲得對應的 16 進位制地址
    • 記憶體管理機制:引用計數器+垃圾回收機制
      • 儲存
      • 引用計數器:對當前引用個數進行計數,系統會去檢查那些引用計數為 0 的物件,然後清除其在記憶體的空間。
      • 垃圾回收:找到迴圈引用,當記憶體中有不再使用的部分時,垃圾收集器就會把他們清理掉。
        • 分代回收
      • 檢視引用計數,需要包 import sys ,sys.getrefcount(物件),注意:這裡也引用了物件,所以計數器會增加 1。
  • 鏈式程式設計

三大特性

  • 封裝:
    • 好處: 1. 使用方便 2. 使用安全 3. 便於維護
  • 繼承
    • 繼承的使用權,並非複製
    • 優點:方便資源重用
    • 單繼承 和 多繼承
    • type 和 object 的區別?
      python 物件導向中有兩種體系,分別是父子關係和例項關係.
      • type 創造(例項化)了 object(例項)
      • type 也繼承自 object(父子)
    • 繼承下的影響:
      • 資源的繼承:只繼承公有屬性和方法&內建方法&受保護的屬性和方法
      • 資源的使用:
        • 不同繼承形態的原則:
          • 單繼承鏈
          • 無重疊的多繼承鏈:優先左側,深度優先
          • 有重疊的多繼承鏈:優先左側,廣度優先
          • 新式類:C3 演算法
          • cls.mro()可以檢視查詢順序
      • 資源的覆蓋
        • self 和 cls,誰呼叫的資源,self 和 cls 就指向誰
      • 資源的累加:
        • 子類比父類多一些自己特有的資源
        • 在被覆蓋的資源上進行新增修改
        • 經典類會產生重複呼叫的問題
        • 新式類使用 super
          • super(param1,param2):,沿著 mro 鏈條來呼叫 | 沿著 param2 的鏈條,找到 param1 的下一個節點.python3 版本都自動找了.
  • 多型
    • 概念:一個類所延伸的多種形態 and 呼叫時的多種形態.
    • python 裡沒有真正意義上的多型.
  • 補充
    • 抽象類
      • 不是具化的類,無法建立
    • 抽象方法
      • 不能具體實現和直接呼叫
    • 無法直接實現, 需要使用 abc 庫
      • import abc; metaclass = abc.ABCMeta; @abc.abstractmethod
      • 抽象方法如果被繼承,那麼子類中一定要實現
  • OOP 設計原則:
    • SOLID:
      • S(Single Responsibility Principle):單一職責原則 - 一個類只負責一項職責
      • O(Open Closed Principle):開放封閉原則 - 對擴充套件開放,對修改關閉
      • L(Liskov Substitution Principle):里氏替換原則 - 使用基類引用的地方必須能使用繼承類的方法
      • I(Interface Segregation Principle):介面分離 - 如果類包含過多介面方法,儘可能的分割方法
      • D(Dependency Inversion Principle):依賴倒置 - 高層模組不應該依賴底層模組

相關文章