课件
前言
软件工程师对软件开发的成败起着至关重要的作用,因此提升自己的编程能力是每一个软件工程师应该修炼的基本功。
编写优雅的程序漂亮完美地解决问题,实现用户需求,也是每一个工程师永远的追求。
编程是一门艺术,它能够展示结构之美、构造之美、表达之美,优美的代码会给人们带来喜悦、舒畅、优雅的享受,编程人员应该以业界良心的高标准要求自己,在编程实践的过程中逐步成长和成熟成为一名优秀的软件工程师。
软件编程工作
高质量的代码不能只是运行正确的,还要求做到可读性强、易于维护和简洁高效。因此,编程的工作除了编写代码之外,还要包括代码审查、单元测试、代码优化、系统构建、集成调试等一系列的工作。
由于软件开发具有迭代的特性,所以编程一般来说也不是能够一次性完成的一个简单过程,而是一个复杂的迭代的过程。
软件开发是由多人协作完成的,程序员编写的代码除了让计算机理解并运行正确之外,还要让其他程序员能够理解和维护,因此代码作为程序员的作品也代表着他的脸面、荣誉和信用,皮尔卡丹曾经说过如果你能真正地钉好一枚钮扣,这比你缝出一件粗制滥造的衣服更有价值。
为了提高代码的可读性,我们应该养成良好的编程习惯,认真对待每一个细节,掌握和执行编程规范,保证代码的清楚、整洁,为整个系统的结构之美打下良好的基础。
软件编程规范
软件编码规范是与特定语言相关的描写如何编写代码的规则集合。说白了就是一组写代码的规矩,就如同交通规则,如果人人遵守,我们的城市交通就能井然有序,减少交通事故,同样的道理,遵照一定的编程规范可以让我们写出来的代码井然有序,进而减少编程事故或者说Bug的发生,避免不必要的错误,同时还能增加代码的可读性、可重用性和可移植性,这样的软件维护变的容易,而现实中软件生命周期的70%成本是维护。
实际上软件编程规范并不存在一个业界的统一标淮,许多公司都会制定自己的规范,这里我们推荐大家阅读、学习并遵守Google公司制定的编程规范,这一套规范相对来说接受的范围更广泛一些,写的也比较具体,不仅告诉了我们该怎么做,还尽量解释了原因。Google的编程规范涵盖了多种编程语言,下面将结合软件工程课程中用到的Python语言,概要地介绍一下Python编程有哪些值得注意的地方。
Python编程规范:程序模板
这里我们给出了一个Python的直接运行程序模板,当然你也可以依照规范编写自己的程序模板。
- 看第一行,它说明了Python程序的运行解释器,对于可以直接执行的文件建议增加这个说明,但是如果是被导入的模块文件可以忽略。
- 文件的基本头部般都是必须要写的,主要包括版权说明、许可声明和模块描述等信息,带有中文的文件要写清楚它的编码形式例如这里是utf-8格式。
- 导入的外部模块应当位于文件顶部,在模块注释和文档字符串之后,在全局变量和常量之前,这样可以方便地检查模块导入是不是正确,有没有导入重复的模块。
- 如果是直接执行的程序,建议创建一个main函数来运行主功能。
- 对于函数和类的定义,需要使用相应的注释来说明其功能。
- 最后一行是用以检查文件是不是直接执行的,这一点是很重要的,因为有一些地方比如pydoc和单元测试,都要求每一不文件是必须可导入的,而且考虑到代码的最大可重用性,即使我们打算某些文件是被直接执行的,也不应该抹杀未来它被其他模块导人的可能性,加上这个对name的判价之后,主程序只有在被直接执行时才会被执行,被作为模玦导入时则不会执行。
Python编程规范:注释
一般来说人们都会使用注释来增加对程序的理解。Python的注释是有两种形式:
- 第一种形式是以 # 号打头的这种真正的注释,一般是用来说明一些实现的原理和难点,上图给的例子是定义了一个取黄金分割点的函数,它的注释说明了黄金分割点的比例,并且说明函数通过直接取0.618这样的方式得出黄金分割点,这样做可以避免使用公式计算,从而实现加速。
- 第二种形式就是像上图示例程序中给出的这样,用前后各三个引号包起来的一个文档字符串,它可以作为包、模块、类、函数之类的文档说明,里面也可以写上使用的示例和单元测试,图中给的例子,用这种方式注释了黄金分割点这个函数,说明了它的基本功能,输入参数还有返回值。
程序注释可以帮助我们更好地理解代码的语义,但是什么是好的注释呢?
这是一位同学写的一个程序,这位同学很用心,总是担心自己的代码不容易被他人理解,所以几乎对每一个语句都加了注释,那么大家觉得这个程序注释写得怎么样?仔细看一下这些注释,就会发现所有的注释只是重复解释了一下各行语句执行的功能,实际上语向本身也是有含义的,比如说前面的这个with open语句,没有它的注释我们也清楚它的意思就是打开一个二进制的只读文件,显然呢这样的注释只是重复了语句的语法含义没有任何的价值,读完之后感觉什么都没说。
另外我们再来看这一段for循环的代码注释,读了这个注释你明白这段代码是干什么吗?看完了以后还是不明白,所以说这个同学虽然在程序中几乎是一行一行地解释代码,但是这些注释对于我们理解代码没有任何帮助,反而影响了我们对程序主要部分的理解,还不如没有注释看起来清楚。
编写程序注释并不是越多越好,而是要讲究实际的价值,不论我们使用什么样的语言来编程,都应该学会只编写够用的注释,重视质量而不是数量:
好的注释应该解释为什么而不是怎么样,所以不要在注释里面重复地描述代码,如果你发现在编写密密麻麻过多的注释的时候,就有必要停下来看一看是不是存在很大的问题,注释其实要写好并不容易,应该要好好斟酌注释里面写什么,写完之后再上下文回顾一下,检查它们是否包含了正确的信息。另外我们在维护代码的同时,也要做好注释的维护
根据上面讲的这些注释原则,我们把前面示例程序的注释进行了重新改写,从现在的这个注释来看,我们可以很清楚地知道,这个程序首先是读入一个文件,在检查输入的合法性之后,把所读入的RGB格式的图像转化为YUV色彩空间的Y通道灰度值,最后再将结果写入另一个文件:
现在的这个代码,是不是看起来清楚多了,如果我们以后再来阅读和维护这段代码,是可以很容易地理解。
遵守良好的注释规范还有一个好处,就是可以用规范的注释自动地生成文档,比如说Python自带了一个pydoc模块,它可以用简单的命令行自动分析脚本文件,根据注释生成可以方便查阅的API文档。上图显示的就是一个示例,如果你想生成更好看的文档,可以用其它的工具,总之许多文档自动化工具都是基于代码的规范注释,所以在编写程序的时候,一定要注意写好注释。
Python编程规范:命名
程序的代码离不开各种命名,我们要给模块命名、给类命名、给函数命名、给变量命名,一致的命名可以减少开发人员很多麻烦,恰如其分的命名也可以大幅度地提高代码的可读性、降低维护成本。由于历史的原因Python库的命名约定有一点混乱,不过现在已经有公认的命名规范了。对于项目中已有的代码因为历史遗留原因,可能不符合本规范,这时候应当看作是一个可容忍的特例允许它的存在,但是在新的代码中不应该延续旧的风格,对于第三方模块也可能不符合这个规范,这时也可以看作是可容忍的一个特例允许其存在,但是在新的代码中也不要再使用第三方模块的风格。
在组装家具的时候通常需要附带一个组装说明,为了更好地理解代码,我们也需要对代码加上必要的注释,或者附带额外的文档。
由于代码在软件的生命周期里会不断地被修改、扩展和维护,相关的文档也就要随着代码的更改而不断地更新,但是现实中经常发生只改代码不改文档的情况,这显然会对以后的维护产生误导,甚至出现危险的错误,所以说最好的方法是不要编写需要外部文档来说明的代码,这样的代码是脆弱的,要确保你的代码本身读起来就很清晰,换句话说,就是要编写自文档化的程序,让代码本身易于理解,而做到这一点的关键在于清晰的代码结构和规范的命名。
来看一个程序,在没有注释的情况下,大家是不是可以很快地明白这段程序是干什么的,也许有的同学会说这段代码看起来太费解了,像i、n1、n2这样的一些变量的命名根本就没有什么任何实际的含义,看了半天也弄不明白它们是什么意思。如果我们把这段代码重构一下,像右边这样,是不是就可以一目了然了:
首先从函数的命名可以知道,它的功能是计算斐波那契数列,根据函数内变量的命名和清晰的代码结构,我们可以了解计算的过程和方法。从这个例子可以看出,通过有意义的命名,我们可以不需要任何注释就能很容易地理解代码,而且这样做更便于后续的维护。
Python编程规范:语句
Python的语句编写也有相应的规范,我们在这里就不再一一地介绍,只是简单地说明部分语句的书写规范:
- 首先Python的语句是不需要在行尾加分号的
- 再一个缩进是Python区分代码块的关键,注意不要用制表符来缩进,也千万不要混用制表符和空格,应该用4个空格来进行缩进
- 类的命名应该是驼峰风格,而且首字母应该大写
- 变量的命名应该是下划线风格
- 使用文件的话应该要显示地调用close,否则很容易造成长时间占用文件的问题,或者也可以通过with语句来更优雅地解决这个问题
- 每一行应该只写一条语句,该换行就换行,一定不要吝啬换行
import 语句在Python程序里很关键,通过它才能做到Python的代码重用,前面我们说过,import的语向要全部放在文件头部,这里再强调一下它的顺序,应该先是import Python的内置模块,然后是第三方模块,最后是自己的模块,有条件的话还应该让它们在各自的部分按字母表顺序排列,一般来说,一条import的语句只import的一个模块,一行写好多模块的话不仅难看还容易出错,如果我们从某个模块import多个对象可能会导致那一行太长,一般建议一行不超过80个字符,这种情况下可以借助括号来进行换行,另外最好也不要用「import*」这种方式来导入某个模块的所有内容,因为这样很容易出现命名空间的冲突。
关于语向Python还有很多灵活的用法,但用的时候应该注意删繁就简,比如Python就有很好用的列表推导,不过使用的时候不要滥用,太复杂的话就很难理解。条件表达式也是很漂亮的一个简短的语法,但是应该注意到要在简单的情况下使用。另外Python还有很多很酷的特性,不过这种酷酷的代码写着试一试玩一玩就行了,千万不要写到真实的项目里,因为它们会大大地增加开发、调试和维护的难度。
关于完整的Python编程规范,大家可以参考Google的官方文档,另外还有一个比较有趣的东西,是Python之禅道,通过import this就可以看到,里面列举了十多条Python程序应该遵循的一些原则。不过非常有意思的是你可以在Python的库目录找到this模块,打开看一看它的源代码,就会发现这些代码完全违背了Python之禅道。总之一个优秀的程序员首先要认真踏实地写好代码,要养成良好的编程习惯,在这门课中我们希望大家自觉实践,编写结构优美、表达简洁清晰的代码。