RWPy4learner 11.3.30 documentation

Version: 11.3.30

模块万岁!

小白的苦恼

由于同学们对通讯录软件的抱怨,小白便琢磨着改进自己的软件。毕竟,仅仅基于函数的通讯录实在是太简陋了,查询函数的参数也很难记住。嗯……小白整理了同学们的反馈意见,决定把词典软件的功能分为两个部分,一部分干实事,一部分负责判断参数然后调用前一个中功能。干实事的那部分应该很容易实现,现在已经有雏形了。但是负责判断参数的那一部分还没有很好的实现,起码连查询帮助(“–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!小白已经有一个命令行的通讯录程序了!

运行之

../_images/malacli.png

小白总是觉得用直觉去理解“类”不大靠谱。这种抽象的概念还是去咨询一下行者们吧!

行者回复:之前小白的所有程序都是由变量与函数分开来的,能不能把变量与函数组合在一起成为一个对象?一个对象既可以储存数据,又 可以当函数使用?可以。这就是……类!

懂了。但小白还要做深入的了解,以便掌握一些独有的特性:

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