Learn Python The Hard Way (python 2.7) ex43.py 学完,分析注释

# -*- coding:utf-8 -*-
from sys import exit
from random import randint

class Scene(object):          #慕课网python进阶3-1:包的每一层下面都要有 __init__文件,此处为何没有?----因为:Sence实例没有相同名字的属性
#----见慕课网 python进阶 4-4  python中初始化实例属性

#虽然我们可以自由地给一个实例绑定各种属性,但是,现实世界中,一种类型的实例应该拥有相同名字的属性。
#例如,Person类应该在创建的时候就拥有 name、gender 和 birth 属性,怎么办?

#在定义Person类时,可以为Person类添加一个特殊的__init__()方法,当创建实例时,__init__()方法被自动调用,我们就能在此为每个实例都统一加上以下属性:……相应地,创建实例时,就必须要提供除 self 以外的参数:……

    def enter(self):
        print "This scene is not yet configured, Subclass it and implement enter()." #此行什么作用?
        exit(1)




 
class Engine(object):
    
    def __init__(self,scene_map):
        self.scene_map = scene_map
#__init__(self, scene_map)其实也可看做是一个特殊的实例方法。
    def play(self):
        current_scene = self.scene_map.opening_scene()
#实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数是完全一样的:
        while True:                 #为什么这样写?可以让程序永远执行下去(除非按键Ctrl+C)
            print "\n--------"         #执行程序最后一行a_game.play() 时先打印出"\n--------"  
            #下面3行if语句是自己添加的代码,修正闯关胜利后程序报错的问题:
            if current_scene == None:
                print "WoW! You are the Hero! You win the game and it will exit! Bye! \n"   ##转义字符\ 很特殊,在字符串里不会直接输出
                exit(1)
            next_scene_name = current_scene.enter()       ### 接着执行下一行,场景的不停切换,除非返回值不是Map类里字典的 key
            
            current_scene = self.scene_map.next_scene(next_scene_name)   ## 执行后跳到上一行,场景的不停切换,除非返回值不是Map类里字典的 key,此时程序返回None 终止
#程序最后一行a_game = Engine( Map('central_corridor') ),即将 Map('central_corridor')传递给 __init__()括号里的scene_map
#注意!!不能写成:***错误《《《《 a_map = CentralCorridor(),a_game = Engine(CentralCorridor())》》》》错误***,具体见Map类的实例方法注释

 
# a_game为Engine的一个实例,a_game.play()  将执行play函数,且 scene_map = Map('central_corridor'),
#current_scene = self.scene_map.opening_scene()即current_scene = Map('central_corridor').opening_scene(),返回CentralCorridor(),   即current_scene = CentralCorridor(),为 CentralCorridor类的一个实例
#next_scene_name = current_scene.enter() 即执行CentralCorridor类里的实例方法enter(),该方法返回一个字符串'death' 或'laser_weapon_armory', 即next_scene_name ='death' 或'laser_weapon_armory',   
###注意!!不能写成:***错误《《《《next_scene_name = CentralCorridor().opening_scene().enter()》》》》错误***,具体见Map类的实例方法注释
#current_scene = self.scene_map.next_scene(next_scene_name)  即current_scene = Map('central_corridor').next_scene('death' 或'laser_weapon_armory') ,   --> current_scene = Death() 或 current_scene = LaserWeaponArmory(), current_scene为 Death类或LaserWeaponArmory类的一个实例。
#此时while循环一直执行,返回上一行next_scene_name = current_scene.enter() , 执行Death类或LaserWeaponArmory类的实例化方法enter()--> 程序退出      或 返回字符串'the bridge'  -->  next_scene_name = 'the bridge',
#接着执行line32: current_scene = self.scene_map.next_scene(next_scene_name)  -->  current_scene = TheBridge()
#此时while循环一直执行,返回上一行next_scene_name = current_scene.enter() ,执行TheBridge类的实例化方法enter()-->            程序退出      或 返回字符串'escape_pod'  -->  next_scene_name = 'escape_pod'
#接着执行line32: current_scene = self.scene_map.next_scene(next_scene_name)  -->  current_scene = TheBridge()
#此时while循环一直执行,返回上一行next_scene_name = current_scene.enter() ,执行EscapePod类的实例化方法enter()-->       返回字符串'death'  或 "finished"  -->   程序退出      或  next_scene_name = "finished"
#接着执行line32: current_scene = self.scene_map.next_scene(next_scene_name)  -->                                              current_scene = Map('central_corridor').next_scene( "finished" ),在后面用code验证一下,返回None(line272) -->  程序报错
#line 31报错:AttributeError: 'NoneType' object has no attribute 'enter'



class Death(Scene):

    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."
    ]
    
    def enter(self):
        print Death.quips[randint(0,len(self.quips)-1)]   ##len(self.quips)-1 == 3 , 这行有何用处?随机输出list quips里的一个字符串元素
        exit(1)                                           ##程序退出
            
        
class CentralCorridor(Scene):

    def enter(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."      
        
        print "What'll you do? A : shoot! , B:dodge! , C:tell a joke"   #此行是自己增加的,为了提高游戏可操作性和通过率
        action = raw_input(">")

        if action == "A":       #更改程序,将原来程序的 "shoot!" 替换成了"A"
            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 a rage and blast you repeatedly in the face until"
            print"you are dead. Then he eats you."
            return 'death'          #
            
        elif action == "B":      #更改程序,将原来程序的 "dodge!" 替换成了"B"
            print "Like a world class boxer you doge, 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 == "C":      #更改程序,将原来程序的 "tell a joke" 替换成了"C"
            print "Lucky for you they made you learn Gothon insults in the academy."
            print "You tell the one Gothon joke you know:"
            print "Lbne ione ine xngo onen, won ren jdglw shld sken snel inglg sndgl lkdg."
            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 squarein the head"
            print "putting him down, then jump through the Weapon Armory door."
            return 'laser_weapon_armory'     #开始将return写成print ,返回值None ,导致 line 31  next_scene_name = current_scene.enter() 报错:AttributeError: 'NoneType' object has no attribute 'enter'   
        else:
            print "DOES NOT COMPUTE!"
            return 'central_corridor'         #SyntaxError: 'return' outside function
                
       
class LaserWeaponArmory(Scene):

    def enter(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 quite, too quite."
        print "You stand up and run to the far side of the room and find the"
        print "neutron bomb in its container. There is a keypadlock 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 colses 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))   #密码由随机的三位数组成
        print 'code is -->', code      #此行为验证程序自己加入的,附加练习3 "通过的秘籍":打印密码
        guess = raw_input("[keypad]>")               #输入1 次密码
        guesses = 0
        
        while guess != code and guesses < 10:            #最多可输入10 次错误的密码
            print "BZZZZEDDD"
            guesses += 1
            guess = raw_input("[keypad]>")
        
        if guess == code:              # 在11次之内密码输对则返回 'the bridge' ,然后执行Engine类里的循环进入 CentralCorridor()场景       
            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'     #注意_不能漏掉!(导致line 31报错:AttributeError: 'NoneType' object has no attribute 'enter' )   不能写成 ''the_bridge''(invalid syntax)
        else:                      #密码连续输错 1+ 10 = 11次 则返回'death',程序退出
            print "The lock buzzes one last time and then you hear a sickening"
            print "metaling 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'
           
           
        
class TheBridge(Scene):
    
    def enter(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 a even uglier"
        print "clown costume then 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."

        print "What'll you do? A : throw the bomb , B:slowly place the bomb "   #此行是自己增加的,为了提高游戏可操作性和通过率        
        action = raw_input(">")
       
        if action == "A":    #更改程序,将原来程序的"throw the bomb" 替换成了"A"
            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 == "B":     #更改程序,将原来程序的 "slowly place the bomb" 替换成了"B"
            print "You point your blaster at the bomb under your arm"
            print "and the Gothons put thier hands up and start to sweat."
            print "You inch backword 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 escaped pod to"
            print "get off this tin can."
            return 'escape_pod'
        else:
            print "DOES NOT COMPUTE!"
            return 'the_bridge'     #开始写错成 "The_bridge",导致line 31报错:AttributeError: 'NoneType' object has no attribute 'enter'  
                    
           
       

class EscapePod(Scene):

    def enter(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)                #随机输出 1~5 中的一个整形
        print "good_pod is %d:" % good_pod       #此行为验证程序自己加入的,附加练习3 "通过的秘籍":打印密码
        guess = raw_input("[pod #]> ")
        
        
        if int(guess) != good_pod:            #猜错则返回 "death" ,后程序退出
            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, crashing your body"
            print "into jam jell."
            return "death"
            
        else:                            #猜对则返回 "finished"
            print "You jump into pod %s and hit the eject button." % guess
            print "The pod easily slides out into space heading to"
            print "the plant below. As it flies to the plant, 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!"
                        
            print " ~~~~~~~~~~~~~~~~~~~~~~ \n ~~HaHa!  You win the game and it will exit! Bye! \n"  #\n不会直接输出,在此处为换行
            exit(1)        #exit() 怎么不执行了?   
            return "finished"     #line 31报错:AttributeError: 'NoneType' object has no attribute 'enter'
        #有两种方法修改作者的程序解决:                    1.(line223~224)在return语句前直接加一行exit()                          2.(line 32~34)在Engine函数里加一个if语句 ,当返回None时,执行exit() 。
        #两种方法都已经写进程序,选择一个即可。
                
        


class Map(object):

    scenes = {
        'central_corridor': CentralCorridor(),
        'laser_weapon_armory':LaserWeaponArmory(),
        'the_bridge':TheBridge(),
        'escape_pod':EscapePod(),
        'death':Death()
    }
        
        
        

    def __init__(self,start_scene):    #Map类实例化时必须传入一个参数start_scene
        self.start_scene = start_scene
        
    def next_scene(self,scene_name):    #next_scene()方法(Map实例属性)return: class Map里字典scenes的具体关键字key(next_scene函数后面()里scene_name,其具体被传递的值)对应的值 value, value本身是一个class(5个场景名称构成的类之一)
        return Map.scenes.get(scene_name)
        
    def opening_scene(self):     # opening_scene()()方法(Map实例属性) return: Map里字典scenes的具体关键字key(Map类实例化时传入的参数start_scene,其具体被传递的值)对应的值 value, value本身是一个class(5个场景名称构成的类之一)
        return self.next_scene(self.start_scene)

##说明:xyzz = Map()为Map类的一个实例,xyzz.next_scene(scene_name) 与   xyzz.opening_scene() 功能相近,都是根据一个字符串(场景名)返回一个类的实例化对象(对应Map类里面字典scenes的某个key和value)

#错误写法:Map().next_scene(scene_name) 与   Map().opening_scene(),如下命令行验证:          
#print Map.next_scene('laser_weapon_armory')
#TypeError: unbound method next_scene() must be called with Map instance as first argument (got str instance instead)

#解释:属性是直接绑定在类上的,所以,访问类属性不需要创建实例,就可以直接访问。 但调用实例方法必须在实例上调用(类的函数必须通过实例化对象来调用,不能直接通过类调用(见python进阶 4-8 python调用实例方法), 改正方法:先设置一个实例化的对象(Map类),再调用Map里的函数(方法)next_scene(),见下面代码:

#xyzz = Map()       #TypeError: __init__() takes exactly 2 arguments (1 given), Map类的对象有共同名字的属性start_scene(即__init__()后面括号里的变量),xyzz = Map()括号里必须传递一个值给start_scene

print'#'*10
xyzz = Map('the_bridge')
print xyzz.next_scene('laser_weapon_armory')     #<__main__.LaserWeaponArmory object at 0x024516D0> 此值改动程序的行数就变改变
print '~'*5
xyzz.next_scene('laser_weapon_armory')        #什么也没有输出,为什么???

print'#'*15
#print Map.opening_scene()     # unbound method opening_scene() must be called with Map instance as first argument (got nothing instead)
print xyzz.opening_scene()     #<unbound method Map.opening_scene>   同上,调用实例方法( opening_scene() )必须在实例(xyzz)上调用
print '~'*5                
xyzz.opening_scene()        #什么也没有输出,为什么???

print'#'*10
print Map.opening_scene       #<unbound method Map.opening_scene>
print xyzz.opening_scene      #<bound method Map.opening_scene of <__main__.Map object at 0x023919F0>>
print '~'*5
print xyzz.opening_scene      #<bound method Map.opening_scene of <__main__.Map object at 0x023919F0>>

print '\/'*15
#接上 line 47 注释,下面开始验证 程序最后执行的代码 current_scene = Map('central_corridor').next_scene( "finished" )
yan = Map('central_corridor')
print xyzz.next_scene( "finished" )   #None   (即print Engine类里的  current_scene)

    


print '/'*10        
a_map = Map('central_corridor')    #a_map 为Map 类的一个实例
# ###  a_map 为 Map类的一个实例,'central_corridor'传递给__init__()括号里的变量start_scene,但此时并未执行Map类实例函数(方法)a_map.opening_scene(), 不会根据Map类里字典scenes里的key返回一个Scene类的实例CentralCorridor()--其本身也是一个类 ,                    故不能写成:***错误《《《《 a_map = CentralCorridor(),其指向一个Scene类》》》》错误***,因为没有调用实例方法。
print a_map                 # <__main__.Map object at 0x02E70910>   <__main__.Map object at 0x02C80930>等,会改变

print '$'*10   
a_game = Engine(a_map)       ###  a_game 为Engine 类的一个实例
#a_game = Engine( Map('central_corridor') ) ,a_game 为Engine 类的一个实例,只是将 Map('central_corridor')传递给__init__(self,scene_map)括号里的变量scene_map,
#故不能写成:   ***错误《《《《将CentralCorridor()传递给__init__()括号里的变量scene_map,a_game=Engine(CentralCorridor()),其指向一个Engine类》》》》错误***
print a_game                  #     <__main__.Engine object at 0x02E70930>  <__main__.Engine object at 0x02C80950>等,会改变

print '&'*10       
print a_game.play           #<bound method Engine.play of <__main__.Engine object at 0x02350950>>

print '!'*10   
print a_game.play()         #这行怎么什么也没有输出呢?(也没占行)也没报错
print '@'*10              ##这行怎么什么也没有输出呢?(也没占行)也没报错
a_game.play()            # 先输出line30 while True: print "\n--------" 的结果(换行)\n------     Engine( Map('central_corridor') ).play   

#a_game = Engine(CentralCorridor()),a_game.play() 即执行Engine(CentralCorridor()).play()







Python进阶书籍,Transform Your Ideas into High-Quality Python Code! Zed Shaw has perfected the world’s best system for becoming a truly effective Python 3.x developer. Follow it and you will succeed—just like the tens of millions of programmers he’s already taught. You bring the discipline, commitment, and persistence; the author supplies everything else. In Learn Python 3 the Hard Way, Zed Shaw taught you the basics of Programming with Python 3. Now, in Learn More Python 3 the Hard Way, you’ll go far beyond the basics by working through 52 brilliantly crafted projects. Each one helps you build a key practical skill, combining demos to get you started and challenges to deepen your understanding. Zed then teaches you even more in 12 hours of online videos, where he shows you how to break, fix, and debug your code. First, you’ll discover how to analyze a concept, idea, or problem to implement in software. Then, step by step, you’ll learn to design solutions based on your analyses and implement them as simply and elegantly as possible. Throughout, Shaw stresses process so you can get started and build momentum, creativity to solve new problems, and quality so you’ll build code people can rely on. Manage complex projects with a programmer’s text editor Leverage the immense power of data structures Apply algorithms to process your data structures Master indispensable text parsing and processing techniques Use SQL to efficiently and logically model stored data Learn powerful command-line tools and skills Combine multiple practices in complete projects It’ll be hard at first. But soon, you’ll just get it—and that will feel great! This course will reward you for every minute you put into it. Soon, you’ll go beyond merely writing code that runs: you’ll craft high-quality Python code that solves real problems. You’ll be a serious Python programmer. Perfect for Everyone Who’s Already Started Working with Python, including Junior Developers and Seasoned Python Pr
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值