日期:2020年3月14日
作者:Commas
註釋:學習就是爲了忘記,什麼是接口類,怎麼將方法變爲屬性;
如果您想了解更多有關Python的知識,那麼請點《我的Python淺談系列目錄》
一、接口類的定義與作用
接口類
實際上就是一個規範子類的類,只不過這個類與別的類不太一樣,接口(內部的方法)本身不實現,子類
繼承接口類,子類需要實現接口的功能,否則無法正常工作。那麼作用也毋庸置疑,就是規範好子類的接口。
定義一個接口類,我們需要abc模塊
(抽象類基類,Abstract Base Classes)中的兩個工具abstractmethod, ABCMeta,詳情如下:
工具 | 說明 |
---|---|
abstractmethod | 抽象類的裝飾器,接口類中的接口需要使用此裝飾器 |
ABCMeta | 抽象類元類 |
from abc import abstractmethod, ABCMeta
def 接口類名(metaclass=ABCMeta):
"""定義您的接口類"""
@abstractmethod
def 方法1(self):
"""定義接口名,但不需要實現其功能,由繼承此類的子類實現"""
pass
@abstractmethod
def 方法2(self):
"""定義接口名,但不需要實現其功能,由繼承此類的子類實現"""
pass
二、圖形的接口類示例
接下來我們來定義一個圖形的接口類GraphicRule
,提供兩個接口,如下:
接口 | 說明 |
---|---|
area | 圖形的面積 |
perimeter | 圖形的周長 |
接口類僅提供接口名的約束,不實現其接口功能,由其子類的矩形類Rectangle
實現,如果子類Rectangle不實現接口類GraphicRule中所有的接口,即area和perimeter,在實例對象的時候,會拋出異常,如我們不實現接口perimeter,將會得到以下異常:
TypeError: Can't instantiate abstract class Rectangle with abstract methods perimeter
在我們看到這個異常的時候,我們就知道我們還有什麼接口沒有實現,異常的解決還不是so easy的事情,完整的示例代碼如下:
from abc import abstractmethod, ABCMeta
class GraphicRule(metaclass=ABCMeta):
"""圖形接口類"""
@abstractmethod
def area(self):
"""面積"""
pass
@abstractmethod
def perimeter(self):
"""周長"""
pass
class Rectangle(GraphicRule):
"""矩形類"""
def __init__(self, b, h):
self.b = b
self.h = h
def area(self):
return self.b*self.h
def perimeter(self):
return (self.b+self.h)*2
# 實例矩形類的一個對象
rect1 = Rectangle(3, 7)
print("矩形面積:{}".format(rect1.area()))
print("矩形周長:{}".format(rect1.perimeter()))
# =======控制檯輸出結果=======
矩形面積:21
矩形周長:20
三、@property讓方法秒變“屬性”
上面我們已經完成了一個接口類的定義以及使用接口類,但是看着那兩個接口的調用,還是感覺有點彆扭。面積area與周長perimeter,在我們的認知中,應該屬於一個對象的屬性纔對;而獲得面積get_area與獲得周長get_perimeter,看上起更像一個對象的方法。那麼我們有沒有可能將方法轉爲屬性呢?答案是有的,使用@property裝飾器,讓方法秒變屬性,如下:
@property
def 方法名(self):
pass
所以示例可修改爲:
from abc import abstractmethod, ABCMeta
class GraphicRule(metaclass=ABCMeta):
"""圖形接口類"""
@abstractmethod
def area(self):
"""面積"""
pass
@abstractmethod
def perimeter(self):
"""周長"""
pass
class Rectangle(GraphicRule):
"""矩形類"""
def __init__(self, b, h):
self.b = b
self.h = h
@property
def area(self):
return self.b*self.h
@property
def perimeter(self):
return (self.b+self.h)*2
rect1 = Rectangle(3, 7)
# (1)註釋以下的方法調用
# print("矩形面積:{}".format(rect1.area()))
# print("矩形周長:{}".format(rect1.perimeter()))
# (2)屬性調用
print("矩形面積:{}".format(rect1.area))
print("矩形周長:{}".format(rect1.perimeter))
# =======控制檯輸出結果=======
矩形面積:21
矩形周長:20
版權聲明:本文爲博主原創文章,如需轉載,請給出:
原文鏈接:https://blog.csdn.net/qq_35844043/article/details/104862886