模块万岁! =============== 小白的苦恼 --------------- 由于同学们对通讯录软件的抱怨,小白便琢磨着改进自己的软件。毕竟,仅仅基于函数的通讯录实在是太简陋了,查询函数的参数也很难记住。嗯……小白整理了同学们的反馈意见,决定把词典软件的功能分为两个部分,一部分干实事,一部分负责判断参数然后调用前一个中功能。干实事的那部分应该很容易实现,现在已经有雏形了。但是负责判断参数的那一部分还没有很好的实现,起码连查询帮助(“--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",找到许多结果。小白读了这些搜索结果,发现下面的链接最有用。 * http://www.doughellmann.com/PyMOTW/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 ): ======================================== [所有命令的列表] Undocumented commands: ====================== help -?add 与 help add 起到一样的作用 啊?原来还要写一个help_xxx的函数啊?于是小白在do_add下面加了一些东西:: def help_add(self): print "add命令:添加一条记录" #帮助信息 有没有用?运行试试看 :: $ python CLI.py >>help Documented commands (type help ): ======================================== 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!小白已经有一个命令行的通讯录程序了! 运行之 .. image :: ../_static/snap/malacli.png 类 ~~~~~~~~~~~~~~~~~~~~~~~ 小白总是觉得用直觉去理解“类”不大靠谱。这种抽象的概念还是去咨询一下行者们吧! 行者回复:之前小白的所有程序都是由变量与函数分开来的,能不能把变量与函数组合在一起成为一个对象?一个对象既可以储存数据,又 可以当函数使用?可以。这就是……类! 懂了。但小白还要做深入的了解,以便掌握一些独有的特性: Python中类的相关文章 ~~~~~~~~~~~~~~~~~~~~~~ 小白在bing中搜索了以下“python 类”,发现有一本介绍Python的教程 * http://woodpecker.org.cn/abyteofpython_cn/chinese/ch11.html 教程里这么说:对象也可以使用 属于 类的函数来具有功能。这样的函数被称为类的方法 有点难以理解,配合代码看看 总结出来 :: 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