python数据接口设计_Python接口与归一化设计
1.什么是接口(interface)
接口(interface)是面向?qū)ο缶幊陶Z(yǔ)言中接口操作的關(guān)鍵字,功能是把所需成員組合起來(lái),用來(lái)裝封一定功能的集合。它好比一個(gè)模板,在其中定義了對(duì)象必須實(shí)現(xiàn)的成員,通過(guò)類(lèi)或結(jié)構(gòu)來(lái)實(shí)現(xiàn)它。接口不能直接實(shí)例化,接口不能包含成員的任何代碼,只定義成員本身。接口成員的具體代碼由實(shí)現(xiàn)接口的類(lèi)提供。
2.歸一化
使用接口的意義在于歸一化,什么叫歸一化:就是只要是基于同一個(gè)接口實(shí)現(xiàn)的類(lèi),那么所有的這些類(lèi)產(chǎn)生的對(duì)象在使用時(shí),從用法上來(lái)說(shuō)都一樣。歸一化的好處在于:
歸一化讓使用者無(wú)需關(guān)心對(duì)象的類(lèi)是什么,只需要的知道這些對(duì)象都具備某些功能就可以了,這極大地降低了使用者的使用難度。
歸一化使得上層的外部使用者可以不加區(qū)分的處理所有接口兼容的對(duì)象集合
1. 就好象linux的泛文件概念一樣,所有東西都可以當(dāng)文件處理,不必關(guān)心它是內(nèi)存、磁盤(pán)、網(wǎng)絡(luò)還是屏幕(當(dāng)然,對(duì)底層設(shè)計(jì)者,當(dāng)然也可以區(qū)分出“字符設(shè)備”和“塊設(shè)備”,然后做出針對(duì)性的設(shè)計(jì):細(xì)致到什么程度,視需求而定)。
2. 再比如:我們有一個(gè)汽車(chē)接口,里面定義了汽車(chē)所有的功能,然后由本田汽車(chē)的類(lèi),奧迪汽車(chē)的類(lèi),大眾汽車(chē)的類(lèi),他們都實(shí)現(xiàn)了汽車(chē)接口,這樣就好辦了,大家只需要學(xué)會(huì)了怎么開(kāi)汽車(chē),那么無(wú)論是本田,還是奧迪,還是大眾我們都會(huì)開(kāi)了,開(kāi)的時(shí)候根本無(wú)需關(guān)心我開(kāi)的是哪一類(lèi)車(chē),操作手法(函數(shù)調(diào)用)都一樣
3.Python中的interface
首先先看一個(gè)Java代碼的接口實(shí)例:
1 //Java 語(yǔ)言中的接口很好的展現(xiàn)了接口的含義: IAnimal.java
2
3 /*
4
5 * Java的Interface很好的體現(xiàn)了我們前面分析的接口的特征:6
7 * 1)是一組功能的集合,而不是一個(gè)功能8
9 * 2)接口的功能用于交互,所有的功能都是public,即別的對(duì)象可操作10
11 * 3)接口只定義函數(shù),但不涉及函數(shù)實(shí)現(xiàn)12
13 * 4)這些功能是相關(guān)的,都是動(dòng)物相關(guān)的功能,但光合作用就不適宜放到IAnimal里面了14
15 */
16 /*Animal接口*/
17 packagecom.oo.demo;18
19 public interfaceIAnimal {20 public voideat();21 public voidrun();22 public voidsleep();23 public voidspeak();24 }25 //========== Pig.java
26 packagecom.oo.demo;27
28 public class Pig implements IAnimal{ //如下每個(gè)函數(shù)都需要詳細(xì)實(shí)現(xiàn)
29 public voideat(){30 System.out.println("Pig like to eat grass");31 }32
33
34 public voidrun(){35 System.out.println("Pig run: front legs, back legs");36 }37
38
39 public voidsleep(){40 System.out.println("Pig sleep 16 hours every day");41 }42
43
44 public voidspeak(){45 System.out.println("Pig can not speak");46 }47 }48
49 //=============== Person.java
50 packagecom.oo.demo;51
52 public class Person2 implementsIAnimal {53 public voideat(){54 System.out.println("Person like to eat meat");55 }56
57 public voidrun(){58
59 System.out.println("Person run: left leg, right leg");60
61 }62
63 public voidsleep(){64 System.out.println("Person sleep 8 hours every dat");65 }66
67
68 public voidspeak(){69 System.out.println("Hellow world, I am a person");70 }71 }
View Code
在python中根本就沒(méi)有一個(gè)叫做interface的關(guān)鍵字,可以使用抽象類(lèi)似的效果:
3.1 抽象類(lèi)
與java一樣,python也有抽象類(lèi)的概念但是同樣需要借助模塊實(shí)現(xiàn),抽象類(lèi)是一個(gè)特殊的類(lèi),它的特殊之處在于只能被繼承,不能被實(shí)例化。
如果說(shuō)類(lèi)是從一堆對(duì)象中抽取相同的內(nèi)容而來(lái)的,那么抽象類(lèi)就是從一堆類(lèi)中抽取相同的內(nèi)容而來(lái)的,內(nèi)容包括數(shù)據(jù)屬性和函數(shù)屬性。比如:我們有香蕉的類(lèi),有蘋(píng)果的類(lèi),有桃子的類(lèi),從這些類(lèi)抽取相同的內(nèi)容就是水果這個(gè)抽象的類(lèi),你吃水果時(shí),要么是吃一個(gè)具體的香蕉,要么是吃一個(gè)具體的桃子。你永遠(yuǎn)無(wú)法吃到一個(gè)叫做水果的東西。
從設(shè)計(jì)角度去看,如果類(lèi)是從現(xiàn)實(shí)對(duì)象抽象而來(lái)的,那么抽象類(lèi)就是基于類(lèi)抽象而來(lái)的。
從實(shí)現(xiàn)角度來(lái)看,抽象類(lèi)與普通類(lèi)的不同之處在于:抽象類(lèi)中只能有抽象方法(沒(méi)有實(shí)現(xiàn)功能),該類(lèi)不能被實(shí)例化,只能被繼承,且子類(lèi)必須實(shí)現(xiàn)抽象方法。這一點(diǎn)與接口有點(diǎn)類(lèi)似,但其實(shí)是不同的。
3.2 抽象類(lèi)與接口
抽象類(lèi)的本質(zhì)還是類(lèi),指的是一組類(lèi)的屬性,包括數(shù)據(jù)屬性(如all_type)和方法屬性(如read、write),而接口只強(qiáng)調(diào)函數(shù)屬性的相似性。抽象類(lèi)是一個(gè)介于類(lèi)和接口直接的一個(gè)概念,同時(shí)具備類(lèi)和接口的部分特性,可以用來(lái)實(shí)現(xiàn)歸一化設(shè)計(jì)。
3.3 在Python中實(shí)現(xiàn)抽象類(lèi)
3.3.1 ABC模塊
Python有一個(gè)模塊:ABC,Abstract Base Class(抽象基類(lèi)),主要定義了基本類(lèi)和最基本的抽象方法,可以為子類(lèi)定義共有的API,不需要具體實(shí)現(xiàn)。相當(dāng)于是Java中的接口或者是抽象類(lèi)。首先看一個(gè)ABC的使用案例:
1 import abc #利用abc模塊實(shí)現(xiàn)抽象類(lèi)
2
3
4 class AllFile(metaclass=abc.ABCMeta):5 all_type = 'file'
6
7 @abc.abstractmethod #定義抽象方法,無(wú)需實(shí)現(xiàn)功能
8 defread(self):9 """子類(lèi)必須定義讀功能"""
10 pass
11
12 @abc.abstractmethod #定義抽象方法,無(wú)需實(shí)現(xiàn)功能
13 defwrite(self):14 """子類(lèi)必須定義寫(xiě)功能"""
15 pass
16
17
18 classTxt(AllFile):19 pass
20
21
22 t1 = Txt() #報(bào)錯(cuò),子類(lèi)沒(méi)有定義抽象方法
運(yùn)行結(jié)果如下:
Traceback (most recent call last):
File"E:/workspace/py3demo/02.py", line 23, in t1= Txt() #報(bào)錯(cuò),子類(lèi)沒(méi)有定義抽象方法
TypeError: Can't instantiate abstract class Txt with abstract methods read, write
發(fā)現(xiàn)運(yùn)行出現(xiàn)錯(cuò)誤“Can't instantiate abstract class Txt with abstract methods read, write”,意思大致是“不能對(duì)抽象類(lèi)Txt的抽象方法read、write進(jìn)行實(shí)例化”!
重新來(lái)設(shè)計(jì):
1 import abc #利用abc模塊實(shí)現(xiàn)抽象類(lèi)
2
3
4 class AllFile(metaclass=abc.ABCMeta):5 all_type = 'file'
6
7 @abc.abstractmethod #定義抽象方法,無(wú)需實(shí)現(xiàn)功能
8 defread(self):9 """子類(lèi)必須定義讀功能"""
10 pass
11
12 @abc.abstractmethod #定義抽象方法,無(wú)需實(shí)現(xiàn)功能
13 defwrite(self):14 """子類(lèi)必須定義寫(xiě)功能"""
15 pass
16
17
18 class Txt(AllFile): #子類(lèi)繼承抽象類(lèi),但是必須定義read和write方法
19 defread(self):20 print('文本數(shù)據(jù)的讀取方法')21
22 defwrite(self):23 print('文本數(shù)據(jù)的讀取方法')24
25
26 class Sata(AllFile): #子類(lèi)繼承抽象類(lèi),但是必須定義read和write方法
27 defread(self):28 print('硬盤(pán)數(shù)據(jù)的讀取方法')29
30 defwrite(self):31 print('硬盤(pán)數(shù)據(jù)的讀取方法')32
33
34 class Process(AllFile): #子類(lèi)繼承抽象類(lèi),但是必須定義read和write方法
35 defread(self):36 print('進(jìn)程數(shù)據(jù)的讀取方法')37
38 defwrite(self):39 print('進(jìn)程數(shù)據(jù)的讀取方法')40
41
42 wenbenwenjian =Txt()43
44 yingpanwenjian =Sata()45
46 jinchengwenjian =Process()47
48 #這樣大家都是被歸一化了,也就是一切皆文件的思想
49 wenbenwenjian.read()50 yingpanwenjian.write()51 jinchengwenjian.read()52
53 print(wenbenwenjian.all_type)54 print(yingpanwenjian.all_type)55 print(jinchengwenjian.all_type)
運(yùn)行結(jié)果如下:
文本數(shù)據(jù)的讀取方法
硬盤(pán)數(shù)據(jù)的讀取方法
進(jìn)程數(shù)據(jù)的讀取方法
file
file
file
3.4.2 拋出異常
可以在抽象類(lèi)的抽象方法中拋出異常,若派生類(lèi)中重新實(shí)現(xiàn)了該抽象方法,則將會(huì)覆蓋掉派生類(lèi)中的派生方法,否則將會(huì)拋出異常:
1 classAllFile(object):2 all_type = 'file'
3
4 defread(self):5 """子類(lèi)必須定義讀功能"""
6 raise NotImplementedError('未實(shí)現(xiàn)該方法!')7
8 defwrite(self):9 """子類(lèi)必須定義寫(xiě)功能"""
10 raise NotImplementedError('未實(shí)現(xiàn)該方法!')11
12
13 classTxt(AllFile):14 pass
15
16
17 t1 = Txt() #報(bào)錯(cuò),子類(lèi)沒(méi)有定義抽象方法
18 t1.write()
運(yùn)行程序,結(jié)果如下:
raise NotImplementedError('未實(shí)現(xiàn)該方法!')
NotImplementedError: 未實(shí)現(xiàn)該方法!
可以看出,繼承于抽象類(lèi)AllFile的txt在未實(shí)現(xiàn)write方法時(shí),拋出了NotImplementedError異常,同樣達(dá)到了限制的功能。
本文參考:
lynnyq:https://blog.csdn.net/lynnyq/article/details/79560867
總結(jié)
以上是生活随笔為你收集整理的python数据接口设计_Python接口与归一化设计的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 拳皇玩家8神月是何许人(拳皇系列下载)
- 下一篇: 因“通货膨胀”,三星美国得州工厂建设预算