[TOC]
## **概述**
### **用途**
ABC,Abstract Base Class(抽象基類),主要定義了基本類和最基本的抽象方法,可以為子類定義共有的API,不需要具體實現。相當于是Java中的接口或者是抽象類。
抽象基類可以不實現具體的方法(當然也可以實現,只不過子類如果想調用抽象基類中定義的方法需要使用super())而是將其留給派生類實現。
### python實現
Python 對于ABC的支持模塊是abc模塊,常用的是如下方法:
`abc.ABCMeta`這是用來生成抽象基礎類的元類。由它生成的類可以被直接繼承。
`abc.ABC`輔助類,讓你可以不用關心元類概念,直接繼承它,就有了ABCMeta元類。使用時注意元類沖突
`@abc.abstractmethod`定義抽象方法.
`@abstractproperty `定義抽象抽象屬性.
### **作用**
抽象基類提供了邏輯和實現解耦的能力,即在不同的模塊中通過抽象基類來調用,可以用最精簡的方式展示出代碼之間的邏輯關系,讓模塊之間的依賴清晰簡單。
同時,一個抽象類可以有多個實現,讓系統的運轉更加靈活。而針對抽象類的編程,讓每個人可以關注當前抽象類,只關注其方法和描述,而不需要考慮過多的其他邏輯,這對協同開發有很大意義。極簡版的抽象類實現,也讓代碼可讀性更高。
## **抽象基類的使用:**
通過`@abc.abstractmethod`將方法聲明為抽象方法。具體化抽象類可以有兩種方式,**一種通過注冊(register),另外一種通過繼承。**
### **1:直接繼承**
直接繼承抽象基類的子類就沒有這么靈活,抽象基類中可以聲明”抽象方法“和“抽象屬性”,只有完全覆寫(實現)了抽象基類中的“抽象”內容后,才能被實例化,而虛擬子類則不受此影響。
**繼承方式的優點**:直接從抽象基類派生子類有一個好處,**除非子類實現抽象基類的抽象方法,否則子類不能實例化。**
~~~
import abc
class PluginBase(metaclass=abc.ABCMeta):
@abc.abstractmethod
def load(self, input):
pass
@abc.abstractmethod
def save(self, output, data):
pass
class SubclassImpementation(PluginBase):
def load(self, input):
return input.read()
def save(self, output, data):
return output.write(data)
# 繼承,必須實現所有抽象方法
print(issubclass(SubclassImpementation, PluginBase))
print(isinstance(SubclassImpementation(), PluginBase))
~~~
### **2:虛擬子類**
將其他的類”注冊“到抽象基類下當虛擬子類(調用register方法),虛擬子類的好處是你實現的第三方子類不需要直接繼承自基類,可以實現抽象基類中的部分API接口,也可以根本不實現,但是issubclass(), issubinstance()進行判斷時仍然返回真值。
**注冊方式的缺點**:不會出現在類的`MRO`(Method Resolution Order),故而也不能通過`super()`來調用抽象方法。當沒有實現抽象方法時,實例化時候不會報錯,只有在調用時候才會報錯。
~~~
import abc
class PluginBase(metaclass=abc.ABCMeta):
@abc.abstractmethod
def load(self, input):
pass
@abc.abstractmethod
def save(self, output, data):
pass
class LocalBaseClass(object):
pass
class RegisteredImplementation(LocalBaseClass):
def load(self, input):
return input.read()
# 注冊,可以不必實現所有抽象方法
PluginBase.register(RegisteredImplementation)
print(issubclass(RegisteredImplementation, PluginBase))
print(isinstance(RegisteredImplementation(), PluginBase))
~~~
- 基礎部分
- 基礎知識
- 變量
- 數據類型
- 數字與布爾詳解
- 列表詳解list
- 字符串詳解str
- 元組詳解tup
- 字典詳解dict
- 集合詳解set
- 運算符
- 流程控制與循環
- 字符編碼
- 編的小程序
- 三級菜單
- 斐波那契數列
- 漢諾塔
- 文件操作
- 函數相關
- 函數基礎知識
- 函數進階知識
- lambda與map-filter-reduce
- 裝飾器知識
- 生成器和迭代器
- 琢磨的小技巧
- 通過operator函數將字符串轉換回運算符
- 目錄規范
- 異常處理
- 常用模塊
- 模塊和包相關概念
- 絕對導入&相對導入
- pip使用第三方源
- time&datetime模塊
- random隨機數模塊
- os 系統交互模塊
- sys系統模塊
- shutil復制&打包模塊
- json&pickle&shelve模塊
- xml序列化模塊
- configparser配置模塊
- hashlib哈希模塊
- subprocess命令模塊
- 日志logging模塊基礎
- 日志logging模塊進階
- 日志重復輸出問題
- re正則表達式模塊
- struct字節處理模塊
- abc抽象類與多態模塊
- requests與urllib網絡訪問模塊
- 參數控制模塊1-optparse-過時
- 參數控制模塊2-argparse
- pymysql數據庫模塊
- requests網絡請求模塊
- 面向對象
- 面向對象相關概念
- 類與對象基礎操作
- 繼承-派生和組合
- 抽象類與接口
- 多態與鴨子類型
- 封裝-隱藏與擴展性
- 綁定方法與非綁定方法
- 反射-字符串映射屬性
- 類相關內置方法
- 元類自定義及單例模式
- 面向對象的軟件開發
- 網絡-并發編程
- 網絡編程SOCKET
- socket簡介和入門
- socket代碼實例
- 粘包及粘包解決辦法
- 基于UDP協議的socket
- 文件傳輸程序實戰
- socketserver并發模塊
- 多進程multiprocessing模塊
- 進程理論知識
- 多進程與守護進程
- 鎖-信號量-事件
- 隊列與生產消費模型
- 進程池Pool
- 多線程threading模塊
- 進程理論和GIL鎖
- 死鎖與遞歸鎖
- 多線程與守護線程
- 定時器-條件-隊列
- 線程池與進程池(新方法)
- 協程與IO模型
- 協程理論知識
- gevent與greenlet模塊
- 5種網絡IO模型
- 非阻塞與多路復用IO實現
- 帶著目標學python
- Pycharm基本使用
- 爬蟲
- 案例-爬mzitu美女
- 案例-爬小說
- beautifulsoup解析模塊
- etree中的xpath解析模塊
- 反爬對抗-普通驗證碼
- 反爬對抗-session登錄
- 反爬對抗-代理池
- 爬蟲技巧-線程池
- 爬蟲對抗-圖片懶加載
- selenium瀏覽器模擬