你在上一節(jié)中發(fā)現(xiàn) dict 的秘密功能了嗎?你可以解釋給自己?jiǎn)??讓我?lái)給你解釋一下,順便和你自己的理解對(duì)比看有什么不同。這里是我們要討論的代碼:
cities['_find'] = find_city
city_found = cities['_find'](cities, state)
你要記住一個(gè)函數(shù)也可以作為一個(gè)變量,``def find_city`` 比如這一句創(chuàng)建了一個(gè)你可以在任何地方都能使用的變量。在這段代碼里,我們首先把函數(shù) find_city 放到叫做 cities 的字典中,并將其標(biāo)記為 '_find'。 這和我們將州和市關(guān)聯(lián)起來(lái)的代碼做的事情一樣,只不過我們?cè)谶@里放了一個(gè)函數(shù)的名稱。
好了,所以一旦我們知道 find_city 是在字典中 _find 的位置,這就意味著我們可以去調(diào)用它。第二行代碼可以分解成如下步驟:
我再教你一個(gè)小技巧。如果你倒著閱讀的話,代碼可能會(huì)變得更容易理解。讓我們來(lái)試一下,一樣是那行:
還有一種方法讀它,這回是“由里向外”。
數(shù)十年的編程下來(lái),我在讀代碼的過程中已經(jīng)用不到上面的三種方法了。我只要瞟一眼就能知道它的意思。甚至給我一整頁(yè)的代碼,我也可以一眼瞄出里邊的 bug 和錯(cuò)誤。這樣的技能是花了超乎常人的時(shí)間和精力才鍛煉得來(lái)的。在磨練的過程中,我學(xué)會(huì)了下面三種讀代碼的方法,它們適用于幾乎所有的編程語(yǔ)言:
下次碰到難懂的語(yǔ)句時(shí),你可以試試這三種方法。
現(xiàn)在我們來(lái)寫這次的練習(xí),寫完后再過一遍,這節(jié)習(xí)題其實(shí)挺有趣的。
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 | import random
from urllib import urlopen
import sys
WORD_URL = "http://learncodethehardway.org/words.txt"
WORDS = []
PHRASES = {
"class ###(###):":
"Make a class named ### that is-a ###.",
"class ###(object):\n\tdef __init__(self, ***)" :
"class ### has-a __init__ that takes self and *** parameters.",
"class ###(object):\n\tdef ***(self, @@@)":
"class ### has-a function named *** that takes self and @@@ parameters.",
"*** = ###()":
"Set *** to an instance of class ###.",
"***.***(@@@)":
"From *** get the *** function, and call it with parameters self, @@@.",
"***.*** = '***'":
"From *** get the *** attribute and set it to '***'."
}
# do they want to drill phrases first
PHRASE_FIRST = False
if len(sys.argv) == 2 and sys.argv[1] == "english":
PHRASE_FIRST = True
# load up the words from the website
for word in urlopen(WORD_URL).readlines():
WORDS.append(word.strip())
def convert(snippet, phrase):
class_names = [w.capitalize() for w in
random.sample(WORDS, snippet.count("###"))]
other_names = random.sample(WORDS, snippet.count("***"))
results = []
param_names = []
for i in range(0, snippet.count("@@@")):
param_count = random.randint(1,3)
param_names.append(', '.join(random.sample(WORDS, param_count)))
for sentence in snippet, phrase:
result = sentence[:]
# fake class names
for word in class_names:
result = result.replace("###", word, 1)
# fake other names
for word in other_names:
result = result.replace("***", word, 1)
# fake parameter lists
for word in param_names:
result = result.replace("@@@", word, 1)
results.append(result)
return results
# keep going until they hit CTRL-D
try:
while True:
snippets = PHRASES.keys()
random.shuffle(snippets)
for snippet in snippets:
phrase = PHRASES[snippet]
question, answer = convert(snippet, phrase)
if PHRASE_FIRST:
question, answer = answer, question
print question
raw_input("> ")
print "ANSWER: %s\n\n" % answer
except EOFError:
print "\nBye"
|
代碼不少,不過還是從頭寫完吧。確認(rèn)它能運(yùn)行,然后玩一下看看。
我玩起來(lái)時(shí)這樣的:
$ python ex41.py
bat.bait(children)
> From bat get the bait function and call it with self and children arguments.
ANSWER: From bat get the bait function, and call it with parameters self, children.
class Brake(object):
def __init__(self, beef)
> class Brake has a __init__ function that takes self and beef parameters.
ANSWER: class Brake has-a __init__ that takes self and beef parameters.
class Cow(object):
def crook(self, cushion)
> class Cow has-a function named crook that takes self and cushion params.
ANSWER: class Cow has-a function named crook that takes self and cushion parameters.
cast = Beetle()
> Set cast to an instance of class Beetle.
ANSWER: Set cast to an instance of class Beetle.
cent.coach = 'appliance'
> From cent get the coach attribute and set it to appliance.
ANSWER: From cent get the coach attribute and set it to 'appliance'.
class Destruction(Committee):
> ^D
Bye