雖說(shuō)將函數(shù)放到字典里是很有趣的一件事情,你應(yīng)該也會(huì)想到“如果 Python 能自動(dòng)為你做這件事情該多好”。事實(shí)上也的確有,那就是 class 這個(gè)關(guān)鍵字。你可以使用 class 創(chuàng)建更棒的“函數(shù)字典”,比你在上節(jié)練習(xí)中做的強(qiáng)大多了。Class(類)有著各種各樣強(qiáng)大的功能和用法,但本書(shū)不會(huì)深入講這些內(nèi)容,在這里,你只要你學(xué)會(huì)把它們當(dāng)作高級(jí)的“函數(shù)字典”使用就可以了。
用到“class”的編程語(yǔ)言被稱作“Object Oriented Programming(面向?qū)ο缶幊蹋闭Z(yǔ)言。這是一種傳統(tǒng)的編程方式,你需要做出“東西”來(lái),然后你“告訴”這些東西去完成它們的工作。類似的事情你其實(shí)已經(jīng)做過(guò)不少了,只不過(guò)還沒(méi)有意識(shí)到而已。記得你做過(guò)的這個(gè)吧:
stuff = ['Test', 'This', 'Out']
print ' '.join(stuff)
其實(shí)你這里已經(jīng)使用了 class。stuff 這個(gè)變量其實(shí)是一個(gè) list class (列表類)。而 ' '.join(stuff) 里調(diào)用函數(shù) join 的字符串 ' ' (就是一個(gè)空格)也是一個(gè) class —— 它是一個(gè) string class (字符串類)。到處都是 class!
還有一個(gè)概念是 object(物件),不過(guò)我們暫且不提。當(dāng)你創(chuàng)建過(guò)幾個(gè) class 后就會(huì)學(xué)到了。你怎樣創(chuàng)建 class 呢?和你創(chuàng)建 ROOMS 的方法差不多,但其實(shí)更簡(jiǎn)單:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | class TheThing(object):
def __init__(self):
self.number = 0
def some_function(self):
print "I got called."
def add_me_up(self, more):
self.number += more
return self.number
# two different things
a = TheThing()
b = TheThing()
a.some_function()
b.some_function()
print a.add_me_up(20)
print b.add_me_up(30)
print a.number
print b.number
# Study this. This is how you pass a variable
# from one class to another. You will need this.
class TheMultiplier(object):
def __init__(self, base):
self.base = base
def do_it(self, m):
return m * self.base
x = TheMultiplier(a.number)
print x.do_it(b.number)
|
Warning
嗯,你開(kāi)始看到 Python 的“疣子”了。Python 是一門比較舊的語(yǔ)言,其中包含很多丑陋的設(shè)計(jì)決定。為了將這些丑陋設(shè)計(jì)掩蓋過(guò)去,他們就做了一些新的丑陋設(shè)計(jì),然后告訴人們讓他們習(xí)慣這些新的壞設(shè)計(jì)。class TheThing(object) 就是其中一個(gè)例子。這里我就不展開(kāi)講了,不過(guò)你也不必操心為什么你的 class 要在后面添一個(gè)(object) ,只要跟著這樣做就可以了,否則將來(lái)總有一天別的 Python 程序員會(huì)吼你讓你這樣做。后面我們?cè)僦v為什么。
你看到參數(shù)里的 self 了吧?你知道它是什么東西嗎?對(duì)了,它就是 Python 創(chuàng)建的額外的一個(gè)參數(shù),有了它你才能實(shí)現(xiàn) a.some_function()` 這種用法,這時(shí)它就會(huì)把\ 前者翻譯成 ``some_function(a) 執(zhí)行下去。為什么用 self 呢?因?yàn)槟愕暮瘮?shù)并不知道你的這個(gè)“實(shí)例”是來(lái)自叫 TheThing 或者別的名字的 class。所以你只要使用一個(gè)通用的名字 self 。這樣你寫(xiě)出來(lái)的函數(shù)就會(huì)在任何情況下都能正常工作。
其實(shí)你可以使用 self 以外的別的字眼,不過(guò)如果你這樣做的話,你就會(huì)成為所有Python 程序員的眾之矢的,所以還是隨大流的好。只有變態(tài)才會(huì)在這里亂改,我教你的沒(méi)錯(cuò)。對(duì)以后會(huì)讀到你的代碼的人好點(diǎn)兒,因?yàn)槟悻F(xiàn)在的代碼10年以后所有的代碼都會(huì)是一團(tuán)糟。
接下來(lái),看到 __init__ 函數(shù)了嗎?這就是你為 Python class 設(shè)置內(nèi)部變量的方式。你可以使用 . 將它們?cè)O(shè)置到 self 上面。另外看到我們使用了 add_me_up() 為你創(chuàng)建的 self.number 加值。后面你可以看到我們?cè)鯓涌梢允褂眠@種方法為數(shù)字加值,然后打印出來(lái)。
接著我創(chuàng)建了另一個(gè)叫 TheMutiplier 的 class,它的功能是做乘法。這樣的 class 其實(shí)是非常沒(méi)必要的,不過(guò)它向你展示了如何將變量和狀態(tài)從一個(gè) class 傳遞到另一個(gè) class。在這里我使用了 TheMultiplier.__init__ 來(lái)從 a.number 來(lái)獲取基本數(shù)值,我還將 b.number 傳遞到 TheMultiplier.do_it 以供調(diào)用。好好研究一下,你需要相關(guān)的知識(shí)來(lái)完成后面的加分習(xí)題。
Class 是很強(qiáng)大的東西,你應(yīng)該好好讀讀相關(guān)的東西。盡可能多找些東西讀并且多多實(shí)驗(yàn)。你其實(shí)知道它們?cè)撛趺从?,只要試試就知道了。其?shí)我馬上就要去練吉他了,所以我不會(huì)讓你寫(xiě)練習(xí)了。你將使用 class 寫(xiě)一個(gè)練習(xí)。
接下來(lái)我們將把習(xí)題41的內(nèi)容重寫(xiě),不過(guò)這回我們將使用 class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | ## Animal is-a object (yes, sort of confusing) look at the extra credit
class Animal(object):
pass
## ??
class Dog(Animal):
def __init__(self, name):
## ??
self.name = name
## ??
class Cat(Animal):
def __init__(self, name):
## ??
self.name = name
## ??
class Person(object):
def __init__(self, name):
## ??
self.name = name
## Person has-a pet of some kind
self.pet = None
## ??
class Employee(Person):
def __init__(self, name, salary):
## ?? hmm what is this strange magic?
super(Employee, self).__init__(name)
## ??
self.salary = salary
## ??
class Fish(object):
pass
## ??
class Salmon(Fish):
pass
## ??
class Halibut(Fish):
pass
## rover is-a Dog
rover = Dog("Rover")
## ??
satan = Cat("Satan")
## ??
mary = Person("Mary")
## ??
mary.pet = satan
## ??
frank = Employee("Frank", 120000)
## ??
frank.pet = rover
## ??
flipper = Fish()
## ??
crouse = Salmon()
## ??
harry = Halibut()
|
這個(gè)版本的游戲和你的上一版效果應(yīng)該是一樣的,其實(shí)有些代碼都幾乎一樣。比較一下兩版代碼,弄懂其中不同的地方,重點(diǎn)需要理解這些東西: