雖說將函數放到字典里是很有趣的一件事情,你應該也會想到“如果 Python 能自動為你做這件事情該多好”。事實上也的確有,那就是 class 這個關鍵字。你可以使用 class 創建更棒的“函數字典”,比你在上節練習中做的強大多了。Class(類)有著各種各樣強大的功能和用法,但本書不會深入講這些內容,在這里,你只要你學會把它們當作高級的“函數字典”使用就可以了。
用到“class”的編程語言被稱作“Object Oriented Programming(面向對象編程)”語言。這是一種傳統的編程方式,你需要做出“東西”來,然后你“告訴”這些東西去完成它們的工作。類似的事情你其實已經做過不少了,只不過還沒有意識到而已。記得你做過的這個吧:
stuff = ['Test', 'This', 'Out']
print ' '.join(stuff)
其實你這里已經使用了 class。stuff 這個變量其實是一個 list class (列表類)。而 ' '.join(stuff) 里調用函數 join 的字符串 ' ' (就是一個空格)也是一個 class —— 它是一個 string class (字符串類)。到處都是 class!
還有一個概念是 object(物件),不過我們暫且不提。當你創建過幾個 class 后就會學到了。你怎樣創建 class 呢?和你創建 ROOMS 的方法差不多,但其實更簡單:
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
嗯,你開始看到 Python 的“疣子”了。Python 是一門比較舊的語言,其中包含很多丑陋的設計決定。為了將這些丑陋設計掩蓋過去,他們就做了一些新的丑陋設計,然后告訴人們讓他們習慣這些新的壞設計。class TheThing(object) 就是其中一個例子。這里我就不展開講了,不過你也不必操心為什么你的 class 要在后面添一個(object) ,只要跟著這樣做就可以了,否則將來總有一天別的 Python 程序員會吼你讓你這樣做。后面我們再講為什么。
你看到參數里的 self 了吧?你知道它是什么東西嗎?對了,它就是 Python 創建的額外的一個參數,有了它你才能實現 a.some_function()` 這種用法,這時它就會把\ 前者翻譯成 ``some_function(a) 執行下去。為什么用 self 呢?因為你的函數并不知道你的這個“實例”是來自叫 TheThing 或者別的名字的 class。所以你只要使用一個通用的名字 self 。這樣你寫出來的函數就會在任何情況下都能正常工作。
其實你可以使用 self 以外的別的字眼,不過如果你這樣做的話,你就會成為所有Python 程序員的眾之矢的,所以還是隨大流的好。只有變態才會在這里亂改,我教你的沒錯。對以后會讀到你的代碼的人好點兒,因為你現在的代碼10年以后所有的代碼都會是一團糟。
接下來,看到 __init__ 函數了嗎?這就是你為 Python class 設置內部變量的方式。你可以使用 . 將它們設置到 self 上面。另外看到我們使用了 add_me_up() 為你創建的 self.number 加值。后面你可以看到我們怎樣可以使用這種方法為數字加值,然后打印出來。
接著我創建了另一個叫 TheMutiplier 的 class,它的功能是做乘法。這樣的 class 其實是非常沒必要的,不過它向你展示了如何將變量和狀態從一個 class 傳遞到另一個 class。在這里我使用了 TheMultiplier.__init__ 來從 a.number 來獲取基本數值,我還將 b.number 傳遞到 TheMultiplier.do_it 以供調用。好好研究一下,你需要相關的知識來完成后面的加分習題。
Class 是很強大的東西,你應該好好讀讀相關的東西。盡可能多找些東西讀并且多多實驗。你其實知道它們該怎么用,只要試試就知道了。其實我馬上就要去練吉他了,所以我不會讓你寫練習了。你將使用 class 寫一個練習。
接下來我們將把習題41的內容重寫,不過這回我們將使用 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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | from sys import exit
from random import randint
class Game(object):
def __init__(self, start):
self.quips = [
"You died. You kinda suck at this.",
"Your mom would be proud. If she were smarter.",
"Such a luser.",
"I have a small puppy that's better at this."
]
self.start = start
def play(self):
next = self.start
while True:
print "\n--------"
room = getattr(self, next)
next = room()
def death(self):
print self.quips[randint(0, len(self.quips)-1)]
exit(1)
def central_corridor(self):
print "The Gothons of Planet Percal #25 have invaded your ship and destroyed"
print "your entire crew. You are the last surviving member and your last"
print "mission is to get the neutron destruct bomb from the Weapons Armory,"
print "put it in the bridge, and blow the ship up after getting into an "
print "escape pod."
print "\n"
print "You're running down the central corridor to the Weapons Armory when"
print "a Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown costume"
print "flowing around his hate filled body. He's blocking the door to the"
print "Armory and about to pull a weapon to blast you."
action = raw_input("> ")
if action == "shoot!":
print "Quick on the draw you yank out your blaster and fire it at the Gothon."
print "His clown costume is flowing and moving around his body, which throws"
print "off your aim. Your laser hits his costume but misses him entirely. This"
print "completely ruins his brand new costume his mother bought him, which"
print "makes him fly into an insane rage and blast you repeatedly in the face until"
print "you are dead. Then he eats you."
return 'death'
elif action == "dodge!":
print "Like a world class boxer you dodge, weave, slip and slide right"
print "as the Gothon's blaster cranks a laser past your head."
print "In the middle of your artful dodge your foot slips and you"
print "bang your head on the metal wall and pass out."
print "You wake up shortly after only to die as the Gothon stomps on"
print "your head and eats you."
return 'death'
elif action == "tell a joke":
print "Lucky for you they made you learn Gothon insults in the academy."
print "You tell the one Gothon joke you know:"
print "Lbhe zbgure vf fb sng, jura fur fvgf nebhaq gur ubhfr, fur fvgf nebhaq gur ubhfr."
print "The Gothon stops, tries not to laugh, then busts out laughing and can't move."
print "While he's laughing you run up and shoot him square in the head"
print "putting him down, then jump through the Weapon Armory door."
return 'laser_weapon_armory'
else:
print "DOES NOT COMPUTE!"
return 'central_corridor'
def laser_weapon_armory(self):
print "You do a dive roll into the Weapon Armory, crouch and scan the room"
print "for more Gothons that might be hiding. It's dead quiet, too quiet."
print "You stand up and run to the far side of the room and find the"
print "neutron bomb in its container. There's a keypad lock on the box"
print "and you need the code to get the bomb out. If you get the code"
print "wrong 10 times then the lock closes forever and you can't"
print "get the bomb. The code is 3 digits."
code = "%d%d%d" % (randint(1,9), randint(1,9), randint(1,9))
guess = raw_input("[keypad]> ")
guesses = 0
while guess != code and guesses < 10:
print "BZZZZEDDD!"
guesses += 1
guess = raw_input("[keypad]> ")
if guess == code:
print "The container clicks open and the seal breaks, letting gas out."
print "You grab the neutron bomb and run as fast as you can to the"
print "bridge where you must place it in the right spot."
return 'the_bridge'
else:
print "The lock buzzes one last time and then you hear a sickening"
print "melting sound as the mechanism is fused together."
print "You decide to sit there, and finally the Gothons blow up the"
print "ship from their ship and you die."
return 'death'
def the_bridge(self):
print "You burst onto the Bridge with the netron destruct bomb"
print "under your arm and surprise 5 Gothons who are trying to"
print "take control of the ship. Each of them has an even uglier"
print "clown costume than the last. They haven't pulled their"
print "weapons out yet, as they see the active bomb under your"
print "arm and don't want to set it off."
action = raw_input("> ")
if action == "throw the bomb":
print "In a panic you throw the bomb at the group of Gothons"
print "and make a leap for the door. Right as you drop it a"
print "Gothon shoots you right in the back killing you."
print "As you die you see another Gothon frantically try to disarm"
print "the bomb. You die knowing they will probably blow up when"
print "it goes off."
return 'death'
elif action == "slowly place the bomb":
print "You point your blaster at the bomb under your arm"
print "and the Gothons put their hands up and start to sweat."
print "You inch backward to the door, open it, and then carefully"
print "place the bomb on the floor, pointing your blaster at it."
print "You then jump back through the door, punch the close button"
print "and blast the lock so the Gothons can't get out."
print "Now that the bomb is placed you run to the escape pod to"
print "get off this tin can."
return 'escape_pod'
else:
print "DOES NOT COMPUTE!"
return "the_bridge"
def escape_pod(self):
print "You rush through the ship desperately trying to make it to"
print "the escape pod before the whole ship explodes. It seems like"
print "hardly any Gothons are on the ship, so your run is clear of"
print "interference. You get to the chamber with the escape pods, and"
print "now need to pick one to take. Some of them could be damaged"
print "but you don't have time to look. There's 5 pods, which one"
print "do you take?"
good_pod = randint(1,5)
guess = raw_input("[pod #]> ")
if int(guess) != good_pod:
print "You jump into pod %s and hit the eject button." % guess
print "The pod escapes out into the void of space, then"
print "implodes as the hull ruptures, crushing your body"
print "into jam jelly."
return 'death'
else:
print "You jump into pod %s and hit the eject button." % guess
print "The pod easily slides out into space heading to"
print "the planet below. As it flies to the planet, you look"
print "back and see your ship implode then explode like a"
print "bright star, taking out the Gothon ship at the same"
print "time. You won!"
exit(0)
a_game = Game("central_corridor")
a_game.play()
|
這個版本的游戲和你的上一版效果應該是一樣的,其實有些代碼都幾乎一樣。比較一下兩版代碼,弄懂其中不同的地方,重點需要理解這些東西: