鍍金池/ 教程/ Python/ exercise40.模塊, 類和對象
附錄 A-練習(xí) 9:生成一個空文件(Touch, New-Item)
附錄 A-練習(xí) 10:復(fù)制文件 (cp)
exercise44.繼承 Vs.包含
附錄 A-練習(xí) 14:刪除文件 (rm)
附錄 A-練習(xí) 11:移動文件 (mv)
exercise46.項目骨架
附錄 A-練習(xí) 3:如果你迷路了
exercise37.復(fù)習(xí)符號
exercise47.自動化測試
exercise3.數(shù)字和數(shù)學(xué)計算
附錄 A-練習(xí) 1:安裝
exercise32.循環(huán)和列表
exercise31.做出決定
exercise42.對象、類、以及從屬關(guān)系
exercise48.更復(fù)雜的用戶輸入
下一步
簡介
附錄 A-練習(xí) 7:刪除路徑 (rmdir)
exercise49.寫代碼語句
exercise18.命名, 變量, 代碼, 函數(shù)
exercise12.提示別人
exercise14.提示和傳遞
exercise40.模塊, 類和對象
附錄 A-練習(xí) 12:查看文件 (less, MORE)
exercise9.打印, 打印, 打印
exercise13.參數(shù), 解包, 變量
exercise30. Else 和 If
exercise28. 布爾表達式
附錄 A-練習(xí) 4:創(chuàng)建一個路徑 (mkdir)
附錄 A-練習(xí) 15:退出命令行 (exit)
exercise25. 更多更多的練習(xí)
exercise6.字符串和文本
exercise2.注釋和井號“#”
exercise21. 函數(shù)的返回值
附錄 A-下一步
exercise1.第一個程序
exercise23. 閱讀代碼
附錄 A-練習(xí) 5:改變當(dāng)前路徑 (cd)
exercise17.更多文件操作
exercise24. 更多的練習(xí)
exercise19.函數(shù)和變量
exercise51.從瀏覽器獲取輸入
exercise22. 到目前為止你學(xué)到了什么?
exercise41.學(xué)會說面向?qū)ο?/span>
exercise52.開始你的 web 游戲
exercise20. 函數(shù)和文件
exercise15.讀文件
exercise45.你來制作一個游戲
exercise10.那是什么?
exercise8.打印, 打印
exercise35.分支和函數(shù)
exercise26. 恭喜你,可以進行一次考試了
exercise33.while 循環(huán)
exercise29. IF 語句
exercise36.設(shè)計和調(diào)試
exercise0.安裝和準(zhǔn)備
exercise50.你的第一個網(wǎng)站
附錄 A-練習(xí) 2:路徑, 文件夾, 名錄 (pwd)
exercise38.列表操作
附錄 A-練習(xí) 6:列出當(dāng)前路徑 (ls)
exercise16.讀寫文件
exercise4.變量和命名
exercise34.訪問列表元素
exercise11.提問
exercise43.基本的面向?qū)ο蟮姆治龊驮O(shè)計
附錄 A-簡介
附錄 A-練習(xí) 8:目錄切換(pushd, popd)
來自老程序員的建議
exercise27. 記住邏輯
exercise5.更多的變量和打印
exercise7.更多的打印(輸出)
附錄 A-練習(xí) 13:輸出文件 (cat)
exercise39.字典,可愛的字典

exercise40.模塊, 類和對象

Python 是一門“面向?qū)ο缶幊陶Z言”。這意味著在 Python 中有一個叫做類的概念,你能通過類用一種特殊的方式構(gòu)建你的軟件。使用類的概念,能給你的程序增添一致性,這樣你可以用一種很輕松方便的方式調(diào)用他們。至少,這是面向?qū)ο蟮睦碚摗?/p>

我現(xiàn)在要通過使用你已經(jīng)知道的字典和模塊等來教你開始學(xué)習(xí)面向?qū)ο缶幊獭㈩惡蛯ο?。我的問題是面向?qū)ο缶幊蹋∣OP)只是普通的怪異。你要為之而奮斗,努力嘗試?yán)斫馕抑v的內(nèi)容,編寫代碼,在下一個練習(xí)中,我會更深入的講解。

我們要開始了。

模塊就像字典

你知道字典是如何被創(chuàng)建以及使用的,它用來將一個事物對應(yīng)到另一個事物。意思就是說如果你有一個字典,字典中包括一個 key "apple",那么你就可以實現(xiàn):

mystuff = {'apple': "I AM APPLES!"}
print mystuff['apple']

記住“從 X 獲取 Y”的說法,然后想一想模塊(module)。你之前已經(jīng)寫過一些模塊,你應(yīng)該知道它們:

1.包含一些函數(shù)和變量的 python 文件 2.你可以導(dǎo)入這個文件 3.你可以用.操作符訪問這個模塊的函數(shù)和變量

想象一下我有一個叫做 mystuff.py 的模塊,在這個模塊中有一個叫做 apple 的函數(shù),下面是 mystuff.py 模塊的代碼:

# this goes in mystuff.py
def apple():
    print "I AM APPLES!"

當(dāng)我寫完以上代碼,我就可以通過 import 來調(diào)用 mystuff 模塊,并訪問 apple 函數(shù):

import mystuff
mystuff.apple()

我還可以增加一個叫做 tangerine 的變量:

def apple():
    print "I AM APPLES!"

# this is just a variable
tangerine = "Living reflection of a dream"

可以用相同的方法來訪問:

import mystuff

mystuff.apple()
print mystuff.tangerine

返回再看字典,你應(yīng)該發(fā)現(xiàn)模塊的使用跟字典是相似的,只不過語法不同,我們比較一下:

mystuff['apple'] # get apple from dict
mystuff.apple() # get apple from the module
mystuff.tangerine # same thing, it's just a variable

也就是說我們在 Python 中有一套通用的模式:

1.有一個 key=value 模式的容器 2.通過 key 從容器中獲取數(shù)據(jù)

在字典中,key 是一個字符串,寫法為[key],在模塊中,key 是一個標(biāo)識符,寫法為.key,在其余的地方,他們幾乎是一樣的。

類就像模塊

你可以認(rèn)為一個模塊就是一個可以存放 Python 代碼的特殊字典,這樣你就可以通過.操作符訪問它。Python 還有一個另外的結(jié)構(gòu)提供相似的功能,就是類(class)。類的作用是組織一系列的函數(shù)和數(shù)據(jù)并將它們放在一個容器里,這樣你可以通過.操作符訪問到它們。

如果我想創(chuàng)建一個類似 mystuff 的類,我需要這樣做:

class MyStuff(object):

    def __init__(self):
        self.tangerine = "And now a thousand years between"

    def apple(self):
        print "I AM CLASSY APPLES!"

這相比于模塊復(fù)雜一些,對比之下肯定會有不同,但是你應(yīng)該能返現(xiàn)這個類就像寫一個包含 apple()方法的“迷你”mystuff 模塊一樣.讓你困惑的地方可能是init()這個方法以及使用 self.tangerine 給 tangerine 賦值。

這正是為什么要使用類而不是僅有模塊的原因:你可以使用 Mystuff 這個類,還可以用它來創(chuàng)建更多個 Mystuff,而他們之間也不會互相沖突。當(dāng)你導(dǎo)入一個模塊時,你的整個項目也就只有一個這個模塊。

在你理解這些之前,你需要明白什么是“對象”,以及如何像使用 Mystuff.py 模塊一樣使用 Mystuff 這個類。

對象就像導(dǎo)入

如果一個類就像一個迷你模塊,那么類也會有一個類似 import 的概念,這個概念被稱為實例化,這只是對創(chuàng)建一種更虛幻更聰明的叫法。當(dāng)一個類被實例化,你就得到一個類的對象。

實例化類的方法就是像調(diào)用函數(shù)一樣調(diào)用這個類:

thing = MyStuff()
thing.apple()
print thing.tangerine

第一行就是實例化的操作,這個操作多像是在調(diào)用一個函數(shù)啊。當(dāng)然了,python 在幕后幫你做了一系列的事情,我?guī)銇砜纯淳唧w的調(diào)用步驟:

1.python 查找 MyStuff() 并確認(rèn)它是你已經(jīng)定義過的類 2.python 創(chuàng)建一個空的對象,該對象擁有你在類中用 def 創(chuàng)建的所有函數(shù) 3.python 看你是否創(chuàng)建了init函數(shù),如果有,調(diào)用該方法初始化你新創(chuàng)建的空對象 4.在 MyStuff 中,init方法有一個額外的變量 self,這是 python 為我創(chuàng)建的一個空的對象,我可以在其上設(shè)置變量。 5.然后,我給 self.tangerine 設(shè)置一首歌詞,然后初始化這個對象 6.python 可以使用這個新創(chuàng)建好的對象,并將其分配給我可以使用的變量 thing。

這就是當(dāng)你調(diào)用一個類的時候,python 做的事情。記住,這并不是把類給你,而是把類作為藍本來創(chuàng)建這種類型東西的副本。

我給了你一個類的簡單工作原理,這樣你就可以基于你所了解的模塊,建立你對類的理解。事實上,在這一點上,類和對象與模塊是有區(qū)別的:

  • 類是用來創(chuàng)建迷你模塊的藍本或定義
  • 實例化是如何創(chuàng)建這些小模塊,并在同一時間將其導(dǎo)入。實例化僅僅是指通過類創(chuàng)建一個對象。
  • 由此產(chǎn)生的迷你模塊被稱為對象,你可以將其分配給一個變量,讓它開始運行

在這一點上,對象和模塊的表現(xiàn)不同,這只是提供一種讓你理解類和對象的方法。

從一個事物中獲取事物

現(xiàn)在我提供給你 3 中方法從一個事物中獲取另一個:

# dict style
mystuff['apples']

# module style
mystuff.apples()
print mystuff.tangerine

# class style
thing = MyStuff()
thing.apples()
print thing.tangerine

類的舉例

你應(yīng)該可以看到在這三個 key=value 的容器類型有一定的相似性,你也可能有一堆問題.記住這些問題,下一節(jié)練習(xí)會訓(xùn)練你關(guān)于“面向?qū)ο蟮脑~匯”。這節(jié)練習(xí)中,我只想讓你輸入這些代碼并保證它能正常運行,這樣能讓你再繼續(xù)下一節(jié)練習(xí)之前獲得一些經(jīng)驗。

class Song(object):

    def __init__(self, lyrics):
        self.lyrics = lyrics

    def sing_me_a_song(self):
        for line in self.lyrics:
            print line

happy_bday = Song(["Happy birthday to you",
                   "I don't want to get sued",
                   "So I'll stop right there"])

bulls_on_parade = Song(["They rally around tha family",
                        "With pockets full of shells"])

happy_bday.sing_me_a_song()

bulls_on_parade.sing_me_a_song()

你應(yīng)該看到的內(nèi)容

$ python ex40.py
Happy birthday to you
I don't want to get sued
So I'll stop right there
They rally around tha family
With pockets full of shells

附加題

1.用本節(jié)學(xué)到的內(nèi)容多寫幾首歌,確定你明白你把一個字符串的列表作為歌詞傳遞進去。 2.把歌詞放進一個單獨的變量,再把這個變量傳遞給類 3.看看你能不能讓這個類做更多的事情,如果沒什么想法也沒關(guān)系,試試看,會有什么 4.在網(wǎng)上搜索一些“面向?qū)ο缶幊獭钡馁Y料,嘗試讓你的大腦填滿這些資料。如果這些資料對你沒有用,也沒關(guān)系,這些東西有一半對我來說也是沒有意義的。

常見問題

Q:為什么我在類里創(chuàng)建init或其他函數(shù)的時候需要使用 self?

如果你不實用 self,像這種代碼 cheese = 'Frank'就是不明確的. 代碼并不清楚你指的是實例的 cheese 屬性,還是一個叫做 cheesed 的全局變量。如果你使用 self.cheese='Frank'代碼就會十分清楚你指的就是實例中的屬性 self.cheese.