原文链接:http://learnpythonthehardway.org/book/ex41.html
在这次的练习中我打算教你如何阐述“面向对象”。我所做的就是告诉你一组关于面向对象中关键定义的词汇,然后我还会给你一些需要要你理解的并不完整的句子。最后,我会给你大量的练习让你去完成使得你对这些词汇和句子加深印象。
单词训练:
> 类: 告诉Python创建一个新的类型。
> 对象 : 两层意思:最基础的一种东西,以及任何事物的实例。
> 实例化:当你告诉Python创建一个类后得到。
> def :在一个类中定义一个函数的方法
> self :在一个类中的函数中,self 是一个变量用来可以被访问的实例化或者对象。
> 继承 :就是一个类从另一个类中继承特征的一个概念,就像你和你父母之间的关系一样。
> 组合 :就是一个类是另一个的一部分的概念,就像车有车轮子一样。
> 属性 :一个属性类就是由一般变量组成该类的一部分就作为该类的属性。
> is-a :就是描述一样东西继承于另一件东西的词汇,就好比说“鲑鱼”是一种“鱼”一样。
> has-a :就是描述一样东西属于另一样东西的组成部分或者特征的词汇,就好比说“鲑鱼”有一张“鱼嘴”一样。
花谢时间把这些做成记忆卡片来记住它们。一般来说靠死记硬背是没有用的,还是得靠多练习,但是做之前你还得了解这些词汇的。
短语训练:
下面在左边我给出了一列代码片段,并且给出了相应的说明:
class X(Y)
"创建一个类名为X的类它继承于Y类。“
class X(object):def __init__(self , J)
”X类有一个带有self 和 J 两个参数的__init__的函数。“
class X(object):def M(self ,J)
”X类有一个名为M的函数,该函数带有 self 和 J 两个参数。“
foo = X()
”设置 foo 为X类的实例化句柄。“
foo.M(J)
”使用foo来得到M函数,并带有参数self ,J来调用它。“
foo.K = Q
”foo 获取类的 K属性并将其设置为Q值。“
这里每一行看到到的 X,Y,M,J,K,Q和 foo 你可以把它当做空白的地方,可以填上自己想填的名称。例如,我也可以像下面这样去写这些句子:
1、"创建一个类名为 ??? 的类它继承于Y类。“
2、” ??? 类有一个带有self 和 ??? 两个参数的__init__的函数。“
3、” ??? 类有一个名为 ??? 的函数,该函数带有 self 和 ??? 两个参数。“
4、”设置 foo 为 ??? 类的实例化句柄。“
5、”使用foo来得到 ??? 函数,并带有参数self , ??? 来调用它。“
6、”foo 获取类的 ??? 属性并将其设置为 ??? 值。“
同样,把这些写到记忆卡片中去,并且多做训练。把Python代码片段写在卡片的前面,解释的句子写在后面。你得当你无论什么时候每次看到这种形式的代码可以准确说出它的含义。不是是形式上类型相同,而是只完全相同的形式。
组合训练:
最后的一个准备就是将词汇训练和短语训练结合起来,我想要你做的练习是下面这些:
1、拿出一张短语卡片来研究。
2、翻过来阅读背面介绍的句子,每次遇到相关的词汇就把该词汇的卡片拿出来训练。
3、将这些句子中的所有这些词汇拿出来训练。
4、一直这样训练直到你感觉厌烦了,然后休息一会再接着做。
一个阅读测试:
我现在有点像Python骇客一样让你不断的不断去训练这些词汇。这里是一个简单脚本示例,你应该能够弄明白,只有一件需要注意的事情就是我使用了一个叫做 urllib 的库来使用其中一些关键字。下面就是这个脚本,你可以输入 oop_test.py来运行这个脚本:
# coding=gbk
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()) # strip()删除字符串开头结尾的空白符
def convert(snippet ,phrase):
class_names = [w.capitalize() for w in # capitalize()使得 w 字符串首字母大写
random.sample(WORDS ,snippet.count("%%%"))] # random.sample从WORDS列表中随机获取指定长度的片段
other_names = random.sample(WORDS ,snippet.count("***"))
results = []
param_names = []
for i in range(0 ,snippet.count("@@@")):
param_count = random.randint(1 ,3) #randint(a ,b) 生成的随机数n: a <= n <= b
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 parmeter lists
for word in param_names:
result = result.replace("@@@" ,word ,1)
results.append(result)
return results
# keep going until they hit CIRL-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"
运行该脚本,试着将“面向对象的短语”翻译成日常用语。你应该可以看到PHRASES字典中有两种不同的形式,你只要输入正确的哪一种就行了。
练习根据英文释义写相应代码:
接下来你应该带有“english"这个参数来运行该脚本,通过与之前相反的操作来进一步训练。
记住这些短语中使用了很多没有意义的关键词,有些人在阅读这些代码时把过多的时间浪费在研究这些变量和类的名称上。人们常常阅读到像”Cork“的这个词汇时会突然很迷惑因为他总是纠结于这个词的含义上去了。在上面的例子中 ,”Cork“只要是一个随意为类取的一个名称而已。不要去过多的深究它的含义,你只要把它当做我给你的类型模板一样就可以了。
阅读更多的代码:
现在你有一个最新的任务就是去阅读更多代码,在这次的练习中,为了阅读这些短语你只是学习了你阅读到这些代码。你要去找到关于类使用的所有文件,然后按照下面要求去做:
1、找出每一个类的名称,并且看看它继承于哪个类。
2、基于上面操作后,将找到的类中的每一个函数及其所带的参数都列举出来。
3、列举出类中自身使用的所有属性。
4、对于每一个属性,给出其对应的类名。
这里训练的目标是通过阅读真正的代码让你看看你刚学习的”模式匹配“的短语别人是怎么使用的。如果你做了足够的练习的话那么之前你看起来很模糊不清楚的地方现在看起来就很清晰易懂了。
学生遇见的常见问题:
result = sentence[:] 做了什么操作?
答:这是Python复制列表的一种操作。你使用的是列表片段语法[:]可以有效的将一个列表中的某个片段从第一个元素到最后一个元素拷贝到另一个列表中去。
运行这个脚本真是太难了!
答:对于这一点我觉得你应该能够输入这些代码并让它运行起来的。这些代码可能在这里或那里使用了一些小技巧但并没有多复杂。你只要按照之前学到的知识去调试脚本你就能弄明白了。