来自 Percal25 号行星的哥顿人
cities['_find'] = find_city
city_found = cities['_find'](cities, state)
这是上一节用到的代码,需要注意的是:一个函数也可以作为一个变量。def find_city
这句创建了一个可以在任何地方都能使用的变量。在上边的代码中,我们首先把函数find_city
放到叫做cities
的字典中,并将其标记为'_find'
。其实就和把州和市关联起来的代码是一样的,只是这段代码放了一个函数名称。
cities = {'CA':'San Francisco','MI':'Detroit','FL':'Jacksonvile'}
cities['NY'] = 'New York'
cities['OR'] = 'Portland'
def find_city(themap, state):
if state in themap:
#print themap #themap 应该就是 cities 中的一个位置
return themap[state]
else:
return "Not found."
cities['_find'] = find_city
while True:
print "State? (ENTER TO QUIT)",
state = raw_input("> ")
if not state: break #在运行过程中实现的功能是按"Enter"退出
city_found = cities['_find'](cities, state)
print city_found
这是上一节的代码,关键部分的代码可以分解为:
-
Python
看到city_found
= 于是知道了需要创建一个变量。 - 然后它读到
cities
,然后知道了它是一个字典 - 然后看到了
['_find']
,于是Python
就从索引找到了字典cities
中对应的位置,并且获取了该位置的内容。 -
['_find']
这个位置的内容是我们的函数find_city
,所以Python
就知道了这里表示一个函数,于是当它碰到(
就开始了函数调用。 -
cities, state
这两个参数将被传递到函数find_city
中,然后这个函数就被运行了。 -
find_city
接着从cities
中寻找states
,并且返回它找到的内容,如果什么都没找到,就返回一个信息说它什么都没找到。 -
Python
find_city
接受返回的信息,最后将该信息赋值给一开始的city_found
这个变量。
书中的原话很令我震惊和期待:
数十年的编程下来,我在读代码的过程中已经用不到上面的三种方法了。我只要瞟一眼就能知道它的意思。甚至给我一整页的代码,我也可以一眼瞄出里边的
bug
和错误。这样的技能是花了超乎常人的时间和精力才锻炼得来的。在磨练的过程中,我学会了下面三种读代码的方法,它们是用户几乎所有的编程语言:
- 从前向后。
- 后向前。
- 逆时针方向。
下次碰到难懂的语句时,你可以试试这三种方法。
练习部分
from sys import exit
from random import randint
def death():
quips = ["You died. You kinda suck at this.",
"Nice job, you died ...jackass.",
"Such a luser.",
"I have a small puppy that's better at this."]
print quips[randint(0, len(quips)-1)]
exit(1)
def central_corridor():
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 hishatefilled 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 "astheGothon's blaster cranks alaser 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 foryouthey made youlearn 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 nottolaugh, 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():
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 guess < 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 tositthere, andfinally theGothons blow up the"
print "ship from their ship and you die."
return 'death'
def the_bridge():
print "You burst onto the Bridge with the neutron destruct bomb"
print "under your arm and surprise 5Gothons 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 aleap for the door. Right as you drop"
print "Gothon shoots you right in the back killing"
print "As you die you see another Gothon frantically"
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"
print "You inch backward tothe door, open it, and then to sweat."
print "You inch backward tothe 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 thebomb isplaced youruntotheescape pod to"
print "get off this tin can."
return 'escape_pod'
else:
print "DOES NOT COMPUTE!"
return "the_bridge"
def escape_pod():
print "You rushthrough theshipdesperately trying tomake 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 %sandhittheeject button." % guess
print "The pod escapes out into the void of space"
print "implodes as the hull ruptures, crushing your body"
print "into jam jelly."
return 'death'
else:
print "You jump into pod %sandhittheeject button." % guess
print "The pod easily slides out into space heading"
print "the planet below. As it flies to the planet, guess to"
print "the planet below. As it flies to the planet,you look"
print "back andseeyour ship implode then explode like a"
print "bright star, taking out the Gothon ship at the same"
print "time. You won!"
exit(0)
ROOMS = {
'death': death,
'central_corridor': central_corridor,
'laser_weapon_armory': laser_weapon_armory,
'the_bridge': the_bridge,
'escape_pod': escape_pod
}
def runner(map, start):
next = start
while True:
room = map[next]
print "\n--------"
next = room()
runner(ROOMS, 'central_corridor')
这段代码对于现在我来说真的是巨大工程,不过还好,输入以后还能运行。不过我把这个代码简化了一下,整个框架就出来了,读起来的时候方便一些。
from sys import exit
from random import randint
def death():
quips = ["You died. You kinda suck at this.",
"Nice job, you died ...jackass.",
"Such a luser.",
"I have a small puppy that's better at this."]
print quips[randint(0, len(quips)-1)]
exit(1)
def central_corridor():
print "Armory and about to pull a weapon to blast you."
action = raw_input("> ")
if action == "shoot!":
print "you are dead. Then he eats you."
return 'death'
elif action == "dodge!":
print "your head and eats you."
return 'death'
elif action == "tell a joke":
return 'laser_weapon_armory'
else:
print "DOES NOT COMPUTE!"
return 'central_corridor'
def laser_weapon_armory():
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 guess < 10:
print "BZZZZEDDD!"
guesses += 1
guess = raw_input("[keypad]> ")
if guess == code:
print "bridge where you must place it in the right spot."
return 'the_bridge'
else:
print "ship from their ship and you die."
return 'death'
def the_bridge():
print "arm and don't want to set it off."
action = raw_input("> ")
if action == "throw the bomb":
print "it goes off."
return 'death'
elif action == "slowly place the bomb":
print "get off this tin can."
return 'escape_pod'
else:
print "DOES NOT COMPUTE!"
return "the_bridge"
def escape_pod():
print "do you take?"
good_pod = randint(1,5)
guess = raw_input("[pod #]> ")
if int(guess) != good_pod:
print "into jam jelly."
return 'death'
else:
print "time. You won!"
exit(0)
ROOMS = {
'death': death,
'central_corridor': central_corridor,
'laser_weapon_armory': laser_weapon_armory,
'the_bridge': the_bridge,
'escape_pod': escape_pod
}
def runner(map, start):
next = start
while True:
room = map[next]
print "\n--------"
next = room()
runner(ROOMS, 'central_corridor')
这样读起来就没那么乱了。
这节还学到一点是“文档字符串”式的注解。举例代码:
def printMax(x, y):
'''打印两个数中的最大值。 两个值必须是整数。'''
x = int(x) # 如果可能,转换为整数
y = int(y)
if x > y:
print(x, 'MAX')
else:
print(y, 'MAX')
printMax(3, 5)
print(printMax.__doc__)
运行结果:
(5, 'MAX')
打印两个数中的最大值。
两个值必须是整数。
这个在某些脚本中还是挺有用的,所以我专门记录了一下。
这一节还涉及到一个从没有听过的名词,有限状态机。状态存储关于过去的信息,就是说:它反映从系统开始到现在时刻的输入变化。转移指示状态变更,并且用必须满足来确使转移发生的条件来描述它。动作是在给定时刻要进行的活动的描述。有多种类型的动作:
进入动作(entry action):在进入状态时进行
退出动作:在退出状态时进行
输入动作:依赖于当前状态和输入条件进行
转移动作:在进行特定转移时进行
今天先看这么多吧,首先得把这节代码看懂再说吧。