模块万岁!¶
小白的苦恼¶
由于同学们对通讯录软件的抱怨,小白便琢磨着改进自己的软件。毕竟,仅仅基于函数的通讯录实在是太简陋了,查询函数的参数也很难记住。嗯……小白整理了同学们的反馈意见,决定把词典软件的功能分为两个部分,一部分干实事,一部分负责判断参数然后调用前一个中功能。干实事的那部分应该很容易实现,现在已经有雏形了。但是负责判断参数的那一部分还没有很好的实现,起码连查询帮助(“–help”)的功能都没有。小白首先想到的是,“可以用if写啊!”。但是小白一想到以后各种命令行参数的判断树不断成长,随着功能的增加,软件的代码会越复杂。小白想到以后代码维护的难度,立刻就觉得使用判断树实在太累人了!哎!
回顾需求¶
小白已经完成了一个可用的基于命令行通讯录软件。但是,小白一直苦于没有好的方便构建命令行程序的方法,目前只能手工编写if语句组成的判断树。使用判断树的工作量将会非常巨大,而且实现的功能也不是很强大。于是迷茫的小白将需求细化如下:
- 读取用户的信息,保存到一个list变量中
- 能够把储存用户信息的list变量保存到本地文件中去
- 用户能够根据姓名来查询记录
- 提供类似python shell的交互式命令行
小白知道,强大的python一定会帮助自己构建出程序,只是自己没有找到罢了。如果连这么简单的需求都实现不了,Python还会这么流行吗?
cmd¶
小白想到了自己身后还有一个巨大的团队——Pyghon邮件列表,(Chinese Python User Group, CPUG,网址为 http://groups.google.com/group/python-cn ),上面的行者一定会帮助自己解决问题的。于是小白到邮件列表上面提问:有没有可以帮助我方便的写出命令行程序的工具呢。行者曰:用CMD吧!
熟悉CMD¶
行者给了一个关键字“CMD”,看着和”command”很像,估计可靠。于是小白,到bing上面查找”Python cmd”,找到许多结果。小白读了这些搜索结果,发现下面的链接最有用。
哦,原来CMD是一个Python模块,可以很容易地实现交互命令行程序。网上说CMD所生成的程序和Python的交互环境相似。看到这里小白立刻来了劲儿,把自己的程序变得和脚本语言一样?爽!
于是小白从网上复制了代码,并修改成了伪代码
'''
CLI.py
命令行通讯录示例。
'''
import cmd #导入cmd模块
class CLI(cmd.Cmd):
def __init__(self): #self是啥子参数?跟一般参数不一样嘛!
cmd.Cmd.__init__(self)
self.prompt = ">>" #是提示符吧!
def do_add(self,arg): #小白自己加的,增加功能
print "添加成功" #鬼知道有没有添加,伪代码嘛
#先写一个功能哈!
cli=CLI()
cli.cmdloop()
小白发现这里面有很多“类”之类的信息。凭着自己的理解,类应该是一个大函数:假设A是一个类,那么A.foo()就是调用大函数里面的小函数了……
运行……没问题!。
但是,小白发现一运行之后,只有一个“>>”提示符在跳。不说新手,连小白自己都不知道如何使用这个软件啊?小白马上明白,得写点帮助什么的告诉用户怎么使用软件。
一查文档小白发现:
- help命令可以查看帮助 比如help add
-后面不加参数也可以,那么就输出
Documented commands (type help <topic>):
========================================
[所有命令的列表]
Undocumented commands:
======================
help
-?add 与 help add 起到一样的作用
啊?原来还要写一个help_xxx的函数啊?于是小白在do_add下面加了一些东西:
def help_add(self):
print "add命令:添加一条记录" #帮助信息
有没有用?运行试试看
$ python CLI.py
>>help
Documented commands (type help <topic>):
========================================
add
Undocumented commands:
======================
help
>>add
添加成功
>>? add
add命令:添加一条记录
>>help add
add命令:添加一条记录
>>
成功!实现了自己的交互环境!小白有点自大起来……待会儿到隔壁寝室给同学们炫耀一番!
填充代码¶
但是上面的代码只能输出一些文字,还需要实现一下实际功能。
小白规划了一下自己的程序:
- add 命令负责添加通讯录信息, 比如 “add john 123-456-789”,用于增加一个叫john的用户和他的电话号码123-456-789。
- view 命令负责查看通讯录信息 比如 “view john”,用于查看john的信息。
小白在玩自己刚刚完成的代码时,还发现,在交互命令行中收到的参数都是字符串类型的,空格被直接无视了。而小白希望将john和123-456-789做成列表元素存储着。“怎么样才能把字符串按空格分割成列表呢?”小白想到了一个算法:“可以用for循环,从字符串第一个字符一个个扫描过去,碰到空格就当成一个列表元素的结束。可是这也太麻烦了。Python肯定有相关的函数!”
于是小白在bing里搜索“python 分割字符串”,搜出一篇:http://www.17jo.com/program/python/base/StringControl.html
不光有字符串分割,还有字符串的其它操作的介绍呢!
其中split函数是分隔字符串的,split(‘/’)就是把字符串从”/”处分割成很多字符串
>>> a="a/b/c/d/e/d/c/f"
>>> a.split('/')
['a', 'b', 'c', 'd', 'e', 'd', 'c', 'f']
>>>
如果要将john和john 123-456-789从”add john 123-456-789”这个命令语句中分隔出来,应该用split(‘ ‘)就可以了。小白根据上面的例子,照葫芦画瓢地写了下面的代码,以从命令行中分隔出参数。
>>> a="add john 123-456-789"
>>> a.split(' ')
['add', 'john', '123-456-789']
>>>
这样就可以得到命令语句中的参数了。 小白立刻动手,在do_add函数中添加了下面的代码代码
list_=txt.split(' ')
namelist.append(list_[0])
namelist.append(list_[1])
txt存放着命令语句,如”add john 123-456-789”。然后通过txt.split(‘ ‘),就把参数一个个按顺序放到namelist这个列表里面了。
do_view方法也要进行相应的修改
if name=="all":
for num in range(len(namelist)):
if num%2==0:
print "Name:"+namelist[num]
print "Tel:"+namelist[num+1]
else:
try:
name1=namelist.index(name)
print 'Name:'+namelist[name1]+'\nTel:'+namelist[name1+1]
except:
print 'Error : This name is not here.'
以上代码基本都是从最初的代码中copy来的,没做什么改动。
再添加相关的help函数!done!小白已经有一个命令行的通讯录程序了!
运行之
类¶
小白总是觉得用直觉去理解“类”不大靠谱。这种抽象的概念还是去咨询一下行者们吧!
行者回复:之前小白的所有程序都是由变量与函数分开来的,能不能把变量与函数组合在一起成为一个对象?一个对象既可以储存数据,又 可以当函数使用?可以。这就是……类!
懂了。但小白还要做深入的了解,以便掌握一些独有的特性:
Python中类的相关文章¶
小白在bing中搜索了以下“python 类”,发现有一本介绍Python的教程
教程里这么说:对象也可以使用 属于 类的函数来具有功能。这样的函数被称为类的方法
有点难以理解,配合代码看看
总结出来
class myprint(): # 定义了一个叫做myprint的类
a='hello' # 建立一个变量
def __init__(self): # __init__是一个方法(函数),叫做__init__的方法在类被“实例化”时会被执行,方法的参数中必须要有一个self
print self.a # 打印
def write(self):
print ",world!"
f=myprint()
f.write()
输出:
hello,world!
小结¶
小白想:
既然模块这么厉害,什么时候我也能有自己的模块?
行者回话:其实你写的程序就是一个模块!在python世界中,任何.py文件都是能够import的!
但是小白这么简陋而且丑陋的代码,谁愿意用呢?还需要修改和整理一下。
嗯!小白确定明天要干的事情了:重构代码,写出自己的模块!
关键词¶
class