下面我根據(jù)MARK Lutz的《Learning Python》中的“大師眼中的OOP”,列一些使用OOP的常見原因辫继。
- 代碼重用腊状。這是很簡單(并且是使用OOP的最主要原因)酱吝。通過支持繼承纳本,類允許通過定制來編程,而不是每次都從頭開始一個項目腋颠。
- 封裝繁成。在對象接口后包裝其實現(xiàn)的細節(jié),從而隔離了代碼的修改對用戶產(chǎn)生的影響淑玫。
- 結(jié)構(gòu)巾腕。類提供了一個新的本地作用域,最小化了變量名沖突絮蒿。他們還提供了一種編寫和查找實現(xiàn)代碼尊搬,以及去管理對象狀態(tài)的自然場所。
- 維護性土涝。類自然而然地促進了代碼的分解佛寿,這讓我們減少了冗余。對虧支持類的結(jié)構(gòu)以及代碼重用但壮,這樣每次只需要修改代碼中一個拷貝就可以了冀泻。
- 一致性。類和繼承可以實現(xiàn)通用的接口蜡饵。這樣代碼不僅有了統(tǒng)一的外表和觀感弹渔,還簡化了代碼的調(diào)試、理解以及維護溯祸。
- 多態(tài)肢专。多態(tài)讓代碼更靈活和有了廣泛的適用性舞肆。(這似乎是OOP的屬性,不是使用它的理由)
此外博杖,對于python2來說椿胯,還有一個叫做“新式類”(new-style)的東西,這個對應(yīng)于前面講過的類欧募,那么前面講過的類就稱為“經(jīng)典”(classic)類压状。但是,對于Python3來講跟继,沒有這種區(qū)別种冬,二者融合。只是在Python2中舔糖,兩個是有區(qū)別的娱两。在基礎(chǔ)部分,依然不講授新式類的問題金吗,如果有興趣十兢,可以自己在GOOGLE中查找有關(guān)資料,也可以隨著我博客的深入摇庙,到下一個階段來學習旱物。
綁定和無綁定方法
類的方法就是函數(shù),只不過這個函數(shù)的表現(xiàn)有點跟前面學過的函數(shù)不一樣卫袒,比如有個self宵呛。當然,也不是必須要有的夕凝,下面就會看到?jīng)]有self的宝穗。既然方法和函數(shù)一樣,本質(zhì)上都是函數(shù)码秉,那么逮矛,函數(shù)那部分學習的時候已經(jīng)明確了:函數(shù)是對象,所以转砖,類方法也是對象须鼎。正如剛才說的,類的方法中府蔗,有的可以有self莉兰,有的可以沒有。為了進行區(qū)別礁竞,進一步做了這樣的定義:
- 無綁定類方法對象:無self
- 綁定實例方法對象:有self
調(diào)用綁定實例方法對象
>>> class MyClass:
... def foo(self,text):
... print text
...
可以用下面的方式調(diào)用實例方法
>>> a = MyClass() #創(chuàng)建類實例
>>> a.foo('hiekay.github.io') #調(diào)用實例方法
hiekay.github.io
>>> a.foo
<bound method MyClass.foo of <__main__.MyClass instance at 0xb74495ac>>
在這個實例方法調(diào)用的時候糖荒,其實已經(jīng)將實例名稱a傳給了self,這就是調(diào)用綁定實例方法對象模捂,有self捶朵。
上面的調(diào)用過程蜘矢,還可以這樣來實現(xiàn):
>>> a = MyClass()
>>> x = a.foo #把實例a和方法函數(shù)foo綁定在一起
>>> x
<bound method MyClass.foo of <__main__.MyClass instance at 0xb74495ac>>
>>> x("hiekay.github.io")
hiekay.github.io
在上面的調(diào)用中,其實相當于前面的調(diào)用過程的分解動作综看。即先將實例a和方法函數(shù)foo綁定在一起品腹,然后賦值給x,這時候x就相當于一個簡單函數(shù)一樣红碑,可以通過上述方式傳入?yún)?shù)舞吭。這里將實例和方法函數(shù)綁定的方式就是運用點號運算(object.method_function)
調(diào)用無綁定類方法對象
所謂類方法對象,就是不通過實例析珊,而是用類進行點號運算來獲得方法函數(shù)(ClassName.method_function)
>>> a = MyClass()
>>> y = MyClass.foo #這里沒有用類調(diào)用
>>> y
<unbound method MyClass.foo>
這樣的調(diào)用羡鸥,就得到了無綁定方法對象,但是忠寻,調(diào)用的時候必須傳入實例做為第一參數(shù)惧浴,如下
>>> y(a,"hiekay.github.io")
hiekay.github.io
否則,就報錯奕剃。請看官特別注意報錯信息
>>> y("hiekay.github.io")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with MyClass instance as first argument (got str instance instead)
>>>
在編程實踐中衷旅,似乎用實例方法調(diào)用更多一下。
文檔字符串
在寫程序的時候纵朋,必須要寫必要的文字說明柿顶,沒別的原因,除非你的代碼寫的非常容易理解操软,特別是各種變量嘁锯、函數(shù)和類等的命名任何人都能夠很容易理解,否則寺鸥,文字說明是不可缺少的。
在函數(shù)、類或者文件開頭的部分寫文檔字符串說明,一般采用三重引號倦淀。這樣寫的最大好處是能夠用help()函數(shù)看衩藤。
"""This is python lesson"""
def start_func(arg):
"""This is a function."""
pass
class MyClass:
"""Thi is my class."""
def my_method(self,arg):
"""This is my method."""
pass
這樣的文檔是必須的。
當然蜈漓,在編程中,有不少地方要用“#”符號來做注釋。一般用這個來注釋局部凉驻。