Python 面向對象筆記

  • 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):依賴倒置 – 高層模組不應該依賴底層模組