通過卡片記憶這些詞語,單獨(dú)的詞語通常沒什么意義,不過我還是要先知道它們的存在。
短語練習(xí)
上面那些x,y,m,q等等都是可以變的。
一個(gè)閱讀測試
這是一個(gè)簡單的腳本可以讓你用來做練習(xí),它只做一件事,就是使用一個(gè)urllib的庫去下載一個(gè)單詞列表。我們把下面的代碼寫到opp_test.py文件中。
import random from urllib import urlopen import sys WORD_URL = "http://learncodethehardway.org/words.txt" WORDS = [] PHRASES = { "class ###(###):": "Make a class named ### that is-a ###.", "class ###(object): def __init__(self, ***)" : "class ### has-a __init__ that takes self and *** parameters.", "class ###(object): def ***(self, @@@)": "class ### has-a function named *** that takes self and @@@ parameters.", "*** = ###()" : "Set *** to an instance of class ###.", "***.***(@@@)" : "From *** get the *** function, and call it with parameters self, @@@.", "***.*** = '***'": "From *** get the *** attribute and set it to '***'." } PHRASE_FIRST = False if len(sys.argv) == 2 and sys.argv[1] == "english": PHRASE_FIRST = True for word in urlopen(WORD_URL).readlines(): WORDS.append(word.strip()) def convert(snippet, phrase): class_names = [w.capitalize() for w in random.sample(WORDS, snippet.count("###"))] other_names = random.sample(WORDS, snippet.count("***")) results = [] param_names = [] for i in range(0, snippet.count("@@@")): param_count = random.randint(1, 3) param_names.append(', '.join(random.sample(WORDS, param_count))) for sentence in snippet, phrase: result = sentence[:] # fake class names for word in class_names: result = result.replace("###", word, 1) # fake other names for word in other_names: result = result.replace("***", word, 1) # fake parameter lists for word in param_names: result = result.replace("@@@", word, 1) results.append(result) return results try: while True: snippets = PHRASES.keys() random.shuffle(snippets) for snippet in snippets: phrase = PHRASES[snippet] question, answer = convert(snippet, phrase) if PHRASE_FIRST: question, answer = answer, question print question raw_input("> ") print "ANSWER: %s " % answer except EOFError: print " Bye"
運(yùn)行這個(gè)例子,它會(huì)盡可能準(zhǔn)確的回答問題。
root@he-desktop:~/mystuff# python oop_test.py
class Deer(object): def __init__(self, connection) > ANSWER: class Deer has-a __init__ that takes self and connection parameters. class Cause(Agreement): > ANSWER: Make a class named Cause that is-a Agreement. animal.driving(arch) > ANSWER: From animal get the driving function, and call it with parameters self, arch. cat = Aftermath() > ANSWER: Set cat to an instance of class Aftermath. cork.card = 'attempt' >
類和對(duì)象
類就像模塊
你可以認(rèn)為模塊就是一個(gè)特殊的字典,它可以保存python代碼,通過 . 號(hào)調(diào)用。python還有一個(gè)類似實(shí)現(xiàn)這種目的的結(jié)構(gòu),叫做類。一個(gè)類包含了很多函數(shù)和數(shù)據(jù),可以通過 . 去訪問它們。
如果我要寫一個(gè)類似mystuff的類,就像這樣:
class mystuff(object): def __int__(self): self.tangerine = "Hello" def apple(self): print "apple"
和模塊比有點(diǎn)復(fù)雜,不過你可以認(rèn)為它就是一個(gè)迷你模塊。讓人疑惑的是__init__()函數(shù)和self.tangerine設(shè)置tangerine變量的值。
這里是用類替代模塊的原因:你可以在一個(gè)程序中使用同一個(gè)類很多次,它們不相互影響,但是一個(gè)程序中只能導(dǎo)入一個(gè)模塊。
理解這些之前,你必須理解什么是對(duì)象。
對(duì)象就像迷你的導(dǎo)入
如果類像模塊,那么類也會(huì)有類型模塊的導(dǎo)入功能。就是實(shí)例化,如果你實(shí)例化一個(gè)類,得到的就是一個(gè)對(duì)象。
使用類的方法類似調(diào)用函數(shù),像這樣:
thing = mystuff() thing.apple() print thing.tangerine
第一步是實(shí)例化,然后調(diào)用它的函數(shù),我們通過上面的代碼分析一下python是怎么按照順序執(zhí)行的:
這就是我們?yōu)槭裁聪裾{(diào)用函數(shù)一樣導(dǎo)入一個(gè)類。
記住,我給出的不是一個(gè)非常準(zhǔn)確類的工作方法,僅僅是為了你能通過模塊而更好的理解類。事實(shí)是,類和對(duì)象和模塊不是一個(gè)東西,老實(shí)說的話,就像下面這樣:
從東西中取出東西
現(xiàn)在有三種方法:
# 字典 mystuff['apple'] # 模塊 mystuff.apple() print mystuff.tangerine # 類 thing = mystuff() thing.apple() print thing.tangerine
第一個(gè)類
你可能還有很多疑問,不要著急,暫時(shí)先放放這些疑問,下一個(gè)練習(xí)我們學(xué)校面向?qū)ο蟮闹R(shí),下面我們先了解一下類的寫法,為下一練習(xí)做準(zhǔn)備。
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 relly around the family", "With pockets full of shells"]) happy_bday.sing_me_a_song() bulls_on_parade.sing_me_a_song()
運(yùn)行結(jié)果
Happy birthday to you I don't want to get sued So I'll stop right there they relly around the family With pockets full of shells
繼承
你必須明白一個(gè)重要的概念,就是類和對(duì)象的不同。問題是,類和對(duì)象沒有真正的區(qū)別,他們在不同的時(shí)間是相同的東西,我將用禪語解釋他們:
魚和鮭魚的區(qū)別是什么呢?
這個(gè)問題是不是很暈?坐下來想想,我的意思是,魚和鮭魚是不同的,但是又是相同的,對(duì)嗎?鮭魚是魚的一種,所以沒有什么不同。但是,鮭魚是魚的一個(gè)分類,并且和其他魚的分類不同。所以鮭魚和魚既相同又不同。
我們不需要真的知道鮭魚和魚的區(qū)別,只要知道鮭魚是魚的一種,而魚還有其他很多種類就可以了。
現(xiàn)在讓我們更近一步,假設(shè)你有三條鮭魚,并且給他們?nèi)∶麨镕rank,Joe,Mary,那么思考這個(gè)問題:
Mary和鮭魚有什么區(qū)別?
這也是一個(gè)奇怪的問題,但是比上個(gè)問題簡單一點(diǎn)。你知道Mary是一條鮭魚,她是鮭魚的一個(gè)實(shí)例。Joe和Frank也是一個(gè)鮭魚的實(shí)例。但是我們說的實(shí)例是什么意思呢?意思就是他們創(chuàng)建于鮭魚,然后現(xiàn)在是一個(gè)真實(shí)東西,鮭魚就像他們的屬性。
現(xiàn)在記住了:魚是一個(gè)類,鮭魚也是一個(gè)類,Mary是一個(gè)對(duì)象。好好想想,你能明白過來的。
魚是一個(gè)類,就是說魚不是一個(gè)真正存在的東西,但是我們通過它的相似的特點(diǎn)去實(shí)例化一些東西,比如,有鱗片,有鰓,生活在水里等,那么這個(gè)東西就是一條魚。
然后一個(gè)專家過來說:”這些魚是鮭魚。“ 這個(gè)專家給這些魚定義一個(gè)新類”鮭魚“,這個(gè)類有一些特別的屬性,長鼻子,紅色的肉,生活在海里,味道美味,好吧,它就是鮭魚。
最后,一個(gè)廚師過來對(duì)專家說:不,你看到的鮭魚在這里,我叫它Mary,我要把她做成一道美味?!爆F(xiàn)在,你就有了一個(gè)鮭魚的實(shí)例(也是魚的實(shí)例)叫做Mary,我們叫這個(gè)實(shí)例是一個(gè)對(duì)象。
現(xiàn)在我們得出:Mary是一種鮭魚,鮭魚是一種魚。對(duì)象是一個(gè)類,而類又是另外一個(gè)類。
寫成代碼是這樣的
這個(gè)概念有些奇怪,不過你只要在創(chuàng)建和使用類的時(shí)候注意一下就可以了,我來告訴你兩個(gè)區(qū)別類和對(duì)象的方法。
第一,你要學(xué)習(xí)兩個(gè)短語“is-a”和“has-a”。is-a就是對(duì)象和類之間通過類的關(guān)系想關(guān)聯(lián),has-a是對(duì)象和類相關(guān)聯(lián)是因?yàn)樗麄儽舜藚⒖肌?/p>
下面用這兩個(gè)關(guān)系標(biāo)注下面的程序,記住,魚和鮭魚是is-a的關(guān)系,鮭魚和鰓是has-a的關(guān)系。
## Animal is-a object (yes, sort of confusing) look at the extra credit class Animal(object): pass ## ?? is-a class Dog(Animal): def __init__(self, name): ## ?? has-a self.name = name ## ?? is-a class Cat(Animal): def __init__(self, name): ## ?? has-a self.name = name ## ?? is-a class Person(object): def __init__(self, name): ## ?? has-a self.name = name ## Person has-a pet of some kind self.pet = None ## ?? has-a class Employee(Person): def __init__(self, name, salary): ## ?? hmm what is this strange magic? super(Employee, self).__init__(name) ## ?? has-a self.salary = salary ## ?? is-a class Fish(object): pass ## ?? is-a class Salmon(Fish): pass ## ?? is-a class Halibut(Fish): pass ## rover is-a Dog rover = Dog("Rover") ## ?? is-a satan = Cat("Satan") ## ?? is-a mary = Person("Mary") ## ?? is-a mary.pet = satan ## ?? is-a frank = Employee("Frank", 120000) ## ?? is-a frank.pet = rover ## ?? is-a flipper = Fish() ## ?? is-a crouse = Salmon() ## ?? is-a harry = Halibut()
關(guān)于 class Name(object)
我讓你使用class Name(object)但是沒有告訴你為什么。因?yàn)榕履慊煜?,并且不知道怎么學(xué)習(xí)。
最初python設(shè)計(jì)類的時(shí)候有很多問題,等發(fā)現(xiàn)的時(shí)候已經(jīng)太晚了,它們必須要支持這種錯(cuò)誤的類。為了修正這個(gè)問題,他們必須設(shè)計(jì)一個(gè)新類方便舊的類能繼續(xù)使用,而且新的類也能正確使用。
這就是為什么類要繼承object類,是不是有點(diǎn)混亂,這里的object指的是類,而不是字面上的解釋為對(duì)象。
你就記住,一個(gè)新的頂級(jí)類必須繼承object就好了。不要太多糾結(jié)于字面上的理解,我們要留著思考更加重要的事情。
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com