《Python基礎教程》第7章 更加抽象
第7章 更加抽象
本章將會介紹如何建立物件,以及多型、封裝、方法、特性、超類以及繼承等概念。
物件的魔力
多型
多型字面意思為有多種形態,在程式語言中意味著即使不知道物件的具體型別,也可以進行某些操作,並且根據物件型別的不同而表現出不同的行為。
為什麼會需要多型呢?如下嘗試用一個例子來說明多型的好處(原書例子有點不好理解,這裡新舉一個例子)。假定某購物網站的商品對應程式類Product, 現在要求計算某個顧客購物車內的所有物品,計算每個物品的價格可能會有如下方法:
def getPrice(p):
if p.type == 'type1':
return p.price
elif p.type == 'type2':
return p.price - discountCalculate(p) #促銷商品
elif p.type == 'type3':
return p.price + taxCalculate(p) #附加稅商品
當出現一種價格計算方式的時候我們要修改程式碼,增加新的分支,分支多的時候會變得難於管理。如果專案已經被整合使用修改會更加麻煩。這時候多型的好處就體現出來了,每種商品都有自己的價格,那麼只要呼叫product.getPrice就能呼叫具體每種商品的價格計算方法。
在Python中我們已經接觸過的多型的運用,比如:
>>> o = 'abc'
>>> o.count('a')
1
>>> o = ['a', 'b', 'c']
>>> o.count('a')
1
其實不只是方法,很多內建的運算子都實現了多型:
>>> 'a' + 'b'
'ab'
>>> 1+2
3
封裝
封裝能對外部作用域隱藏內部實現細節只知道如何呼叫即可。
繼承
繼承是想要擴充套件功能,有不想寫重複的做法。
類和型別
類到底是什麼
類即型別或者種類,所有的物件都屬於某一個類,稱為類的例項。比如,鳥是鳥類的例項,鳥類有可能有很多子類(subclass)如“百靈鳥”;反過來,鳥類是“百靈鳥”的超類(superclass)。
在物件導向程式設計中,所有例項都包含類的方法,所有子類都必須繼承或者過載超類的方法,並且子類中可以新增自己特有的方法。
建立自己的類
__metaclass__ = type
class Person:
def setName(self, name):
self.name = name
def getName(self):
return self.name
def greet(self):
print 'Hello, I am %s' % self.name
foo = Person()
bar = Person()
foo.setName('foo')
print foo.getName()
bar.name = 'bar'
print bar.name
foo.greet()
$ python class.py
foo
bar
Hello, I am foo
如上為類的建立和使用,注意第一行程式碼:宣告新式類需要在模組或者指令碼開始地方放置該行(不細究)。
特性、函式和方法
class Bird:
song = 'Squaawk'
def sing(self):
print self.song
bird = Bird()
bird.sing()
singsong = bird.sing
singsong()
$ python class.py
Squaawk
Squaawk
某些程式語言覺得直接通過'物件.屬性'的方式訪問破壞了封裝性,但Python並不支援私有形式(儘管有一些小技巧可以達到私有特性的效果,不是目前學習的重點先跳過)。
類的名稱空間
所有位於class中間的程式碼都在類名稱空間中,這個名稱空間可以由所有的類的例項訪問。需要注意類的定義就是執行程式碼塊,因此如下定義方式雖然傻但是是可以的:
class C:
print 'Class C is defined...'
$ python class.py
Class C is defined...
在類中可以定義供所有成員訪問的變數,如下是一個例子(在Java中叫類變數,通常在定義指明MemberCounter.members;而在Python中定義是直接寫在members類中。兩者呼叫的時候同樣使用MemberCounter.members):
class MemberCounter:
members = 0
def init(self):
MemberCounter.members += 1
m1 = MemberCounter()
m1.init()
print m1.members
m2 = MemberCounter()
m2.init()
print m2.members
$ python class.py
1
2
呼叫超類
子類可以擴充套件超類的定義,既可以覆寫超類的方法,也可以直接使用超類方法而不用自己再定義:
class Filter():
def init(self):
self.blocked = []
def filter(self, sequence):
return [x for x in sequence if x not in self.blocked]
class SPAMFilter(Filter):
def init(self):
self.blocked = ['SPAM']
filter = Filter()
filter.init()
print filter.filter([1,2,3])
spamFilter = SPAMFilter()
spamFilter.init()
print spamFilter.filter(['SPAM','SPAM', 'zip','lotus','SPAM']);
$ python class.py
[1, 2, 3]
['zip', 'lotus']
Filter類的blocked為[]因此不會對任何內容進行過濾;而在子類SPAMFilter中,我們覆寫了init方法,仍舊使用超類的filter方法,因此所有'SPAM'的字串都被過濾掉了。
介紹幾個和類相關的常用方法
s = SPAMFilter()
#想要知道一個類是否是另一個類的子類:
print issubclass(SPAMFilter, Filter) #True
print issubclass(Filter, SPAMFilter) #False
#想要知道一個類已知基類(們):
print SPAMFilter.__bases__ # (<class __main__.Filter at 0x1004b8c18>,)
#想要知道一個物件是否是一個類的例項:
print isinstance(s, SPAMFilter) #True
print isinstance(s, Filter) #True
#想要知道一個物件屬於哪個類
print s.__class__ #__main__.SPAMFilter
多個超類
類可以繼承自多個超類,除非非常熟悉否則應該儘量避免使用,如下是一個多重繼承的例子:
class Calculator:
def calculate(self, expression):
self.value = eval(expression)
class Talk():
def talk(self):
print 'My value is: %s' % self.value
class CalculatorTalk(Calculator, Talk):
pass
ct = CalculatorTalk()
ct.calculate('2+3')
ct.talk()
$ python class.py
My value is: 5
介面和內省
介面的概念和多型有關,即處理多型物件時候只需要關係公開的方法和特性,因此需要檢測物件是否真正實現了方法和特性。如下介紹兩個檢測的方法,第一個是所需方法是否存在,第二個是是所需方法否可呼叫。
hasattr(ct, 'talk') # True
hasattr(ct, 'test') # False
callable(getattr(ct, 'talk', None)) # True
callable(getattr(ct, 'test', None)) # False
相關文章
- Python基礎教程(第2版) 入門好書~~~Python
- Python基礎教程Python
- python 教程_【python 基礎教程詳解】Python
- python基礎教程|菜鳥教程Python
- Python Numpy基礎教程Python
- JavaSE基礎:抽象類Java抽象
- Python基礎面試題30問!Python基礎教程Python面試題
- python-基礎教程-pprintPython
- 【莫煩】python基礎教程Python
- Python 基礎知識教程Python
- Python scrapy基礎教程(三)Python
- Python scrapy基礎教程(二)Python
- Python scrapy基礎教程(一)Python
- 《jQuery基礎教程(第3版)》譯者序jQuery
- python學習筆記(1)--《python基礎教程》第1章內容總結Python筆記
- Gurobi基礎教程(Python版)-系列教程2Python
- Python抽象基類abcPython抽象
- Python Flask基礎教程(入門)PythonFlask
- Python基礎教程01 Hello World!Python
- Python基礎教程03 - 序列 (sequence)Python
- Python基礎教程06 - 迴圈Python
- Python基礎教程07 - 函式Python函式
- Python基礎教程04 運算Python
- 《Python基礎教程》小小有感Python
- Python基礎教程.18214570Python
- Java基礎-抽象類和介面Java抽象
- Java基礎-抽象工廠模式Java抽象模式
- 《SQL基礎教程(第2版)》簡單筆記SQL筆記
- 好書推薦——JavaScript基礎教程(第8版)JavaScript
- Python 快速教程(基礎篇02):基礎資料型別Python資料型別
- (Python基礎教程之七)Python字串操作Python字串
- Python基礎教程該如何學習?Python
- 1、python機器學習基礎教程——簡述Python機器學習
- Python 3基礎教程16-類Python
- Python Django基礎教程(五)(表單)PythonDjango
- Python Django基礎教程(一)(入門)PythonDjango
- Python基礎教程視訊集錦Python
- python基礎教程視訊下載Python