python定義接口繼承類invalid syntax解決辦法
1
2
3
4
5
6
7
|
class
s_all(metaclass
=
abc.ABCMeta):
#python2.7用此方法定義接口繼承
# __metaclass__ = abc.ABCMeta
@abc
.abstractmethod
def
read(
self
):
pass
|
pyhton2.7會報錯,此方法用於python3+
pyhton2.7應用次方法定義
1
2
3
4
5
6
7
|
class
s_all():
#python2.7用此方法定義接口繼承
__metaclass__
=
abc.ABCMeta
@abc
.abstractmethod
def
read(
self
):
pass
|
Python之抽象類、抽象方法
抽象類中只能有抽象方法,子類繼承抽象類時,不能通過實例化使用其抽象方法,必須實現該方法。
Python2
class CopyBase(object): def save(self): raise NotImplementedError class CopyPaper(CopyBase): def __init__(self): pass def save(self): print("copy paper") class CopyQuestion(CopyBase): def __init__(self): pass copy_paper = CopyPaper() copy_paper.save() copy_question = CopyQuestion() copy_question.save() result: copy paper Traceback (most recent call last): copy_question.save() raise NotImplementedError NotImplementedError
這里以NotImplementedError的形式實現了抽象類和抽象方法,如果子類不實現該方法會拋出異常
Python3
在Python3中引入了abc模塊,通過@abc.abstractmethod可以更加簡潔地使用抽象類,抽象方法。
import abc class CopyBase(metaclass=abc.ABCMeta): @abc.abstractmethod def save(self): pass class CopyPaper(CopyBase): def __init__(self): pass def save(self): print("copy paper") class CopyQuestion(CopyBase): def __init__(self): pass copy_paper = CopyPaper() copy_paper.save() copy_question = CopyQuestion() copy_question.save() result: copy paper Traceback (most recent call last): copy_question = CopyQuestion() TypeError: Can't instantiate abstract class CopyQuestion with abstract methods save
從abc模塊引入類abstractmethod和類ABCMeta,自定義的CopyBase類繼承抽象類ABCMeta,在類CopyBase中定義save方法,
添加裝飾器abcstractmethod,CopyPaper類和CopyQuestion繼承CopyBase類,分別實例化CopyPaper和CopyQuestion,
CopyQuestion類沒有實現save方法,因此會拋出異常。
Python抽象類和接口類
一、抽象類和接口類
繼承有兩種用途:
一:繼承基類的方法,並且做出自己的改變或者擴展(代碼重用)
二:聲明某個子類兼容於某基類,定義一個接口類Interface,接口類中定義了一些接口名(就是函數名)且並未實現接口的功能,子類繼承接口類,並且實現接口中的功能.
實踐中,繼承的第一種含義意義並不很大,甚至常常是有害的。因為它使得子類與基類出現強耦合。
繼承的第二種含義非常重要。它又叫“接口繼承”。
接口繼承實質上是要求“做出一個良好的抽象,這個抽象規定了一個兼容接口,使得外部調用者無需關心具體細節,可一視同仁的處理實現了特定接口的所有對象”——這在程序設計上,叫做歸一化。
1.做出良好的抽象類,2.規定兼容接口 3.調用者可以無需關心具體實現細節,可以一視同仁處理實現特定接口的所有對象。
#做出一個良好的抽象 class Payment(object): #規定了一個兼容接口 def pay(self): pass #微信支付 class WeChatPay(object): def pay(self,money): print('微信支付了%s'%money) #支付寶支付 class AliPay(object): def pay(self,money): print('支付寶支付了%s'%money) #蘋果支付 class ApplePay(object): def pay(self,money): print('蘋果支付了%s'%money) def pay(obj,money): obj.pay(money) weixin = WeChatPay() alipay = AliPay() applepay = ApplePay() #調用者無需關心具體實現細節,可以一視同仁的處理實現了特定接口的所有對象 pay(weixin,100) pay(alipay,200) pay(applepay,300)
歸一化使得高層的外部使用者可以不加區分的處理所有接口兼容的對象集合——就好象linux的泛文件概念一樣,所有東西都可以當文件處理,不必關心它是內存、磁盤、網絡還是屏幕(當然,對底層設計者,當然也可以區分出“字符設備”和“塊設備”,然后做出針對性的設計:細致到什么程度,視需求而定)。
1
2
|
依賴倒置原則:
高層模塊不應該依賴低層模塊,二者都應該依賴其抽象;抽象不應該應該依賴細節;細節應該依賴抽象。換言之,要針對接口編程,而不是針對實現編程
|
二、抽象類
什么是抽象類
與java一樣,python也有抽象類的概念但是同樣需要借助模塊實現,抽象類是一個特殊的類,它的特殊之處在於只能被繼承,不能被實例化
為什么要有抽象類
如果說類是從一堆對象中抽取相同的內容而來的,那么抽象類就是從一堆類中抽取相同的內容而來的,內容包括數據屬性和函數屬性。
比如我們有香蕉的類,有蘋果的類,有桃子的類,從這些類抽取相同的內容就是水果這個抽象的類,你吃水果時,要么是吃一個具體的香蕉,要么是吃一個具體的桃子。。。。。。你永遠無法吃到一個叫做水果的東西。
從設計角度去看,如果類是從現實對象抽象而來的,那么抽象類就是基於類抽象而來的。
從實現角度來看,抽象類與普通類的不同之處在於:抽象類中有抽象方法,該類不能被實例化,只能被繼承,且子類必須實現抽象方法。這一點與接口有點類似,但其實是不同的,即將揭曉答案
在python中實現抽象類
#一切皆文件 import abc #利用abc模塊實現抽象類 class All_file(metaclass=abc.ABCMeta): all_type='file' @abc.abstractmethod #定義抽象方法,無需實現功能 def read(self): '子類必須定義讀功能' pass @abc.abstractmethod #定義抽象方法,無需實現功能 def write(self): '子類必須定義寫功能' pass # class Txt(All_file): # pass # # t1=Txt() #報錯,子類沒有定義抽象方法 class Txt(All_file): #子類繼承抽象類,但是必須定義read和write方法 def read(self): print('文本數據的讀取方法') def write(self): print('文本數據的讀取方法') class Sata(All_file): #子類繼承抽象類,但是必須定義read和write方法 def read(self): print('硬盤數據的讀取方法') def write(self): print('硬盤數據的讀取方法') class Process(All_file): #子類繼承抽象類,但是必須定義read和write方法 def read(self): print('進程數據的讀取方法') def write(self): print('進程數據的讀取方法') wenbenwenjian=Txt() yingpanwenjian=Sata() jinchengwenjian=Process() #這樣大家都是被歸一化了,也就是一切皆文件的思想 wenbenwenjian.read() yingpanwenjian.write() jinchengwenjian.read() print(wenbenwenjian.all_type) print(yingpanwenjian.all_type) print(jinchengwenjian.all_type)
三、抽象類和抽象接口
抽象類的本質還是類,指的是一組類的相似性,包括數據屬性(如all_type)和函數屬性(如read、write),而接口只強調函數屬性的相似性。
抽象類是一個介於類和接口直接的一個概念,同時具備類和接口的部分特性,可以用來實現歸一化設計
在python中,並沒有接口類這種東西,即便不通過專門的模塊定義接口,我們也應該有一些基本的概念。
1.多繼承問題
在繼承抽象類的過程中,我們應該盡量避免多繼承;
而在繼承接口的時候,我們反而鼓勵你來多繼承接口
接口隔離原則: 使用多個專門的接口,而不使用單一的總接口。即客戶端不應該依賴那些不需要的接口。
在抽象類中,我們可以對一些抽象方法做出基礎實現;
而在接口類中,任何方法都只是一種規范,具體的功能需要子類實現
1.多繼承問題 在繼承抽象類的過程中,我們應該盡量避免多繼承; 而在繼承接口的時候,我們反而鼓勵你來多繼承接口 2.方法的實現 在抽象類中,我們可以對一些抽象方法做出基礎實現; 而在接口類中,任何方法都只是一種規范,具體的功能需要子類實現