<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            習題 42: 物以類聚?

            雖說將函數放到字典里是很有趣的一件事情,你應該也會想到“如果 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()
            

            你應該看到的結果?

            這個版本的游戲和你的上一版效果應該是一樣的,其實有些代碼都幾乎一樣。比較一下兩版代碼,弄懂其中不同的地方,重點需要理解這些東西:

            1. 怎樣創建一個 class Game(object) 并且放函數到里邊去。
            2. __init__ 是一個特殊的初始方法,可以預設重要的變量在里邊。
            3. 為 class 添加函數的方法是將函數在 class 下再縮進一階,class 的架構就是通過縮進實現的,這點很重要。
            4. 你在函數里的內容又縮進了一階。
            5. 注意冒號的用法。
            6. 理解 self 的概念,以及它在 __init__playdeath 里是怎樣使用的。
            7. 研究 play 里的 getattr 的功能,這樣你就能明白 play 所做的事情。其實你可以手動在 Python 命令行實驗一下,從而弄懂它。
            8. 最后我們怎樣創建了一個 Game ,然后通過 play() 讓所有的東西運行起來。

            加分習題?

            1. 研究一下 __dict__ 是什么東西,應該怎樣使用。
            2. 再為游戲添加一些房間,確認自己已經學會使用 class 。
            3. 創建一個新版本,里邊使用兩個 class,其中一個是 Map ,另一個是 Engine 。提示: 把 play 放到 Engine 里面。

            Project Versions

            Table Of Contents

            Previous topic

            習題 41: 來自 Percal 25 號行星的哥頓人(Gothons)

            Next topic

            習題 43: 你來制作一個游戲

            This Page

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线