linyawen

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

简明 Python 编程规范
编码

转自 http://fenxiangdizhi.5d6d.com/thread-341-1-1.html


    所有的 Python 脚本文件都应在文件头标上 # -*- coding:utf-8 -*- 。设置编辑器,默认保存为 utf-8 格式。
注释
    业界普遍认同 Python 的注释分为两种的概念,一种是由 # 开头的“真正的”注释,另一种是 docstrings。前者表明为何选择当前实现以及这种实现的原理和难点,后者表明如何使用这个包、模块、类、函数(方法),甚至包括使用示例和单元测试。
    坚持适当注释原则。对不存在技术难点的代码坚持不注释,对存在技术难点的代码必须注释。但与注释不同,推荐对每一个包、模块、类、函数(方法)写 docstrings,除非代码一目了然,非常简单。
缩进
    Python 依赖缩进来确定代码块的层次,行首空白符主要有两种:tab 和空格,但严禁两者混用。如果使用 tab 缩进,设定 tab 为 4 个空格。
    公司内部推荐使用 4 个空格的 tab 进行缩进。
空格
    空格在 Python 代码中是有意义的,因为 Python 的语法依赖于缩进,在行首的空格称为前导空格。在这一节不讨论前导空格相关的内容,只讨论非前导空格。非前导空格在 Python 代码中没有意义,但适当地加入非前导空格可以增进代码的可读性。
1) 在二元算术、逻辑运算符前后加空格:如 a = b + c;
2) 在一元前缀运算符后不加空格,如 if !flg: pass;
3) “:”用在行尾时前后皆不加空格,如分枝、循环、函数和类定义语言;用在非行尾时两端加空格,如 dict 对象的定义 d = {‘key’ : ’value’}。
4) 括号(含圆括号、方括号和花括号)前后不加空格,如 do_something(arg1, arg2),而不是 do_something( arg1, arg2 );
5) 逗号后面加一个空格,前面不加空格;s
空行
    适当的空行有利于增加代码的可读性,加空行可以参考如下几个准则:
1) 在类、函数的定义间加空行;
2) 在 import 不同种类的模块间加工行;
3) 在函数中的逻辑段落间加空行,即把相关的代码紧凑写在一起,作为一个逻辑段落,段落间以空行分隔;
断行
    尽管现在的宽屏显示器已经可以单屏显示超过 256 列字符,但本规范仍然坚持行的最大长度不得超过 78 个字符的标准。折叠长行的方法有以下几种方法:
1) 为长变量名换一个短名,如:
    this.is.a.very.long.variable_name = this.is.another.long.variable_name
    应改为:
    variable_name1 = this.is.a.very.long.variable_name
    variable_name2 = this.is.another.variable_name
    variable_name1 = variable_name2s
2) 在括号(包括圆括号、方括号和花括号)内换行,如:
    class Edit(CBase):
        def __init__(self, parent, width, 
                                font = FONT, color = BLACK, pos = POS, style = 0):
    或:
    very_very_very_long_variable_name = Edit(parent, \
                                                                            width, \
                                                                            font, \
                                                                            color, \
                                                                            pos)
    如果行长到连第一个括号内的参数都放不下,则每个元素都单独占一行:
    very_very_very_long_variable_name = ui.widgets.Edit( \
                                                                                    panrent, \
                                                                                    width, \
                                                                                    font, \
                                                                                    color, \
                                                                                    pos)
3) 在长行加入续行符强行断行,断行的位置应在操作符前,且换行后多一个缩进,以使维护人员看代码的时候看到代码行首即可判定这里存在换行,如:
if color == WHITE or color == BLACK \
or color == BLUE: # 注意 or 操作符在新行的行首而不是旧行的行尾
do_something(color);
命名
    一致的命名可以给开发人员减少许多麻烦,而恰如其分的命名则可以大幅提高代码的可读性,降低维护成本。
常量
常量名所有字母大写,由下划线连接各个单词,如
WHITE = 0XFFFFFF
THIS_IS_A_CONSTANT = 1
变量
    变量名全部小写,由下划线连接各个单词,如
color = WHITE
this_is_a_variable = 1
    不论是类成员变量还是全局变量,均不使用 m 或 g 前缀。私有类成员使用单一下划线前缀标识,多定义公开成员,少定义私有成员。
    变量名不应带有类型信息,因为 Python 是动态类型语言。如 iValue、names_list、dict_obj 等都是不好的命名。
函数
    函数名的命名规则与变量名相同。

    类名单词首字母大写,不使用下划线连接单词,也不加入 C、T 等前缀。如:
class ThisIsAClass(object):
    passs
模块
    模块名全部小写,对于包内使用的模块,可以加一个下划线前缀,如
module.py
_internal_module.py

    包的命名规范与模块相同。
缩写
    命名应当尽量使用全拼写的单词,缩写的情况有如下两种:
1) 常用的缩写,如 XML、ID等,在命名时也应只大写首字母,如
class XmlParser(object):pass
2) 命名中含有长单词,对某个单词进行缩写。这时应使用约定成俗的缩写方式,如去除元音、包含辅音的首字符等方式,例如:
function 缩写为 fn
text 缩写为 txt
object 缩写为 obj
count 缩写为 cnt
number 缩写为 num,等。
特定命名方式
    主要是指 __xxx__ 形式的系统保留字命名法。项目中也可以使用这种命名,它的意义在于这种形式的变量是只读的,这种形式的类成员函数尽量不要重载。如
class Base(object):
    def __init__(self, id, parent = None):
        self.__id__ = id
        self.__parent__ = parent
    def __message__(self, msgid):
        # …略
其中 __id__、__parent__ 和 __message__ 都采用了系统保留字命名法。
语句
import
    import 语句有以下几个原则需要遵守:
1) import 的次序,先 import Python 内置模块,再 import 第三方模块,最后 import 自己开发的项目中的其它模块;这几种模块中用空行分隔开来。
2) 一条 import 语句 import 一个模块。
3) 当从模块中 import 多个对象且超过一行时,使用如下断行法(此语法 py2.5 以上版本才支持):
from module import (obj1, obj2, obj3, obj4,
                                    obj5, obj6)
4) 不要使用 from module import *,除非是 import 常量定义模块或其它你确保不会出现命名空间冲突的模块。
赋值
    对于赋值语言,主要是不要做无谓的对齐,如:
a   = 1     # 这是一个行注释
variable  = 2     # 另一个行注释
fn   = callback_function  # 还是行注释
没有必要做这种对齐,原因有两点:一是这种对齐会打乱编程时的注意力,大脑要同时处理两件事(编程和对齐);二是以后阅读和维护都很困难,因为人眼的横向视野很窄,把三个字段看成一行很困难,而且维护时要增加一个更长的变量名也会破坏对齐。直接这样写为佳:
a = 1 # 这是一个行注释
variable = 2 # 另一个行注释
fn = callback_function # 还是行注释
分枝和循环
    对于分枝和循环,有如下几点需要注意的:
1) 不要写成一行,如:
if !flg: pass 和 for i in xrange(10): print i都不是好代码,应写成
if !flg:
    pass
for i in xrange(10):
    print i
注:本文档中出现写成一行的例子是因为排版的原因,不得作为编码中不断行的依据。
2) 条件表达式的编写应该足够 pythonic,如以下形式的条件表达式是拙劣的:
if len(alist) != 0: do_something()
if alist != []: do_something()
if s != “”: do_something()
if var != None: do_something()
if var != False: do_something()
上面的语句应该写成:
if seq: do_somethin() # 注意,这里命名也更改了
if var: do_something()
3) 用得着的时候多使用循环语句的 else 分句,以简化代码。
已有代码
    对于项目中已有的代码,可能因为历史遗留原因不符合本规范,应当看作可以容忍的特例,允许存在;但不应在新的代码中延续旧的风格。
    对于第三方模块,可能不符合本规范,也应看作可以容忍的特例,允许存在;但不应在新的代码中使用第三方模块的风格。
    tab 与空格混用的缩进是不可容忍的,在运行项目时应使用 –t 或 –tt 选项排查这种可能性存在。出现混用的情况时,如果是公司开发的基础类库代码,应当通知类库维护人员修改;第三方模块则可以通过提交 patch 等方式敦促开发者修正问题。
已有风格
    开发人员往往在加入项目之前已经形成自有的编码风格,加入项目后应以本规范为准编写代码。特别是匈牙利命名法,因为带有类型信息,并不适合 Python 编程,不应在 Python 项目中应用。

 
 
 
 
 
 
2.2 Python的编码规则
Python语言有自己独特的编码规则,包括命名规则、代码书写规则等。本节将详细介绍Python中常用的规则,并解释这些规则的原理和由来。
2.2.1 命名规则
Python语言有一套自己的命名规则,用户也可以借鉴Java语言的命名规则以形成自己编码的规则。命名规则并不是规定,只是一种习惯用法。变量名的首字符必须是字母或下划线,首字符之外的字符可以由字母、数字或下划线组成,并且不能使用Python的保留字。下面介绍几种常见的规则。
1.变量名、包名、模块名
变量名通常由字母和下划线组成,包名、模块名通常用小写字母,如【例2-1】所示。
【例2-1】演示变量名、包名、模块名的规范写法。
# 变量、模块名的命名规则  # Filename: ruleModule.py  _rule = "rule information" 第1行代码是程序代码的注释,关于Python语言的注释请参见2.2.5节。
第2行代码也是程序的注释,用于声明模块的名称,模块名用小写字母。也可以不指定模块名,以py后缀的文件就是一个模块。模块名就是文件名。
第4行代码定义了一个全局变量_rule。
2.类名、对象名
类名首字母用大写,其他字母采用小写。对象名用小写字母。类的属性和方法名以对象作为前缀,对象通过操作符“.”访问属性和方法。类的私有变量、私有方法以两个下划线作为前缀。如【例2-2】所示。
【例2-2】演示类的定义和实例化的规范写法。
class Student:# 类名用大写字母  __name = ""# 私有实例变量前必须有两个下划线  def __init__(self, name):  self.__name = name# self相当于Java中的this  def getName(self):# 方法名首字母用小写,其后每个单词的首字母用大写  return self.__name   if __name__ == "__main__":  student = Student("borphi")# 对象名用小写字母   printstudent.getName() 第1行代码定义了一个名为Student的类,类名首字母大写。
第2行代码定义了一个私有的实例变量,变量名前有两个下划线。
第4行代码使用self前缀说明__name变量属于Student类。
第5行代码定义了一个公有的方法,方法名首字母小写,其后的单词“Name”首字母大写。函数的命名规则与此相同。
第9行代码创建了一个student对象,对象名小写。
说明关于面向对象的编程知识将在第8章详细介绍,读者此时只要知道类、对象、属性以及方法的书写方式即可。
3.函数名
函数名通常采用小写,并用下划线或单词首字母大写来增加名称的可读性,导入的函数以模块名作为前缀。为了演示导入函数前缀的写法,下面使用了生成随机数的模块random。该模块有一个函数randrange()。该函数可以根据给定的数字范围生成随机数。randrange()的声明如下所示:
randrange(start, stop\[, step\]) 参数start表示生成随机数所在范围的开始数字。
参数stop表示生成随机数所在范围的结束数字,但不包括数字stop。
参数step表示从start开始往后的步数。生成的随机数在\[start,stop - 1\]的范围内,取值等于start + step。
例如:
randrange(1, 9, 2) 随机数的范围在1、3、5、7之间取得。
【例2-3】演示函数的规范写法,其中定义了一个函数compareNum(),该函数用于比较两个数字的大小,并返回对应的结果。
# 函数中的命名规则  import random  def compareNum(num1, num2):  if(num1 > num2):  return 1 elif(num1 == num2):  return 0 else:  return -1 num1 = random.randrange(1, 9)  num2 = random.randrange(1, 9)  print "num1 =", num1  print "num2 =", num2  print compareNum(num1, num2) 第2行代码导入了random模块。
第4行代码定义了一个函数compareNum(),参数num1、num2为待比较的两个变量。
第5行到第10行代码比较两个数的大小,根据比较结果返回不同的结果。
第11行、第12行代码调用random模块的randrange()返回两个随机数。
第13行、第14行代码输出随机数,不同的机器、不同的执行时间得到的随机数均不相同。
第15行代码调用compareNum(),并把产生的两个随机数作为参数传入。
良好的命名习惯可以提高编程效率,使代码阅读者在不了解文档的情况下,也能理解代码的内容。
下面以变量的命名为例,说明如何定义有母实际含义的名称。许多程序员对变量的命名带有随意性,如使用i、j、k等单个字母。代码阅读者并不知道这些变量的实际含义,需要阅读文档或仔细查看源代码才能了解其含义。
【例2-4】演示变量命名不规范的写法。
# 不规范的变量命名写法  sum = 0 i = 2000 j = 1200 sum = i + 12 * j 这段代码定义了一个求和变量sum,以及两个变量i、j。如果只看代码片段,并不知道该运算的含义是什么,需要通读整个函数或功能模块才能理解此处各个变量的含义。
【例2-5】演示符合命名规则的写法。
# 规范的变量命名写法  sumPay = 0 bonusOfYear = 2000 monthPay = 1200 sumPay = bonusOfYear + 12 * monthPay bonusOfYear表示年终奖金、monthPay表示月薪,因此sumPay表示全年的薪水。使变量的名字有实际含义可以节省阅读程序的时间,能更快地理解程序的含义。
注意变量的命名应尽可能的表达此变量的作用,尽量避免使用缩写,以便使任何人都能理解变量名的含义。不要过多的担心变量名的长度,长的变量名往往能更表达清楚该变量的作用。
以上讨论的命名方式同样适用于模块名、类名、方法名、属性名等。遵守命名规则会带来很多好处。统一的命名规则便于程序开发团队合作开发同一个项目;便于统一代码的风格,理解不同程序员编写的代码;命名规范的变量名可以使程序代码更容易被理解;避免项目中随意命名变量的情况,促进程序员之间的交流。规则并不是绝对的,统一规则、表达清楚名称的含义才是制定规则的目的。
2.2.2 代码缩进与冒号
代码缩进是指通过在每行代码前键入空格或制表符的方式,表示每行代码之间的层次关系。任何编程语言都需要代码缩进规范程序的结构,采用代码缩进的编程风格有利于代码的阅读和理解。对于C、C++、Java等语言,代码缩进只是作为编程的一种良好习惯而延承下来。对于Python而言,代码缩进是一种语法,Python语言中没有采用花括号或begin...end...分隔代码块,而是使用冒号和代码缩进来区分代码之间的层次。
使用IDE开发工具或EditPlus等编辑器书写代码时,编辑器会自动缩进代码、补齐冒号,提高编码效率。
【例2-6】演示代码中的条件语句采用代码缩进的语法。
# Filename: code.py  x = 1 if x == 1:  print "x =", x# 代码缩进  else:  print "x =", x# 代码缩进  x = x + 1# 代码缩进  print "x =", x 第2行代码创建了变量x,并赋值为1。在赋值运算符的两侧各添加一个空格,这是一种良好的书写习惯,提高了程序的可读性。
第3行代码使用了条件语句if,判断x的值是否等于1。if表达式后输入了一个冒号,冒号后面的代码块需要缩进编写。本行代码与第1行代码处于同一个层次,所以直接从最左端书写代码。
第4行代码表示x的值等于1时输出结果。当if条件成立时,程序才能执行到第4行,所以第4行代码位于第3行代码的下一个层次。在编码时,首先在最左端输入4个空格或制表键,然后再书写print语句。输出结果:
x = 1 第5行代码的else保留字后是一段新的代码块。当x的值不等于1时,程序将执行第6、第7行代码。
第6行、第7行代码采用缩进式的代码风格。
第8行代码输出结果:
x = 1 python对代码缩进的要求非常严格。如果程序中不采用代码缩进的编码风格,将抛出一个IndentationError异常。
【例2-7】演示错误的缩进方式。
x = 0 if x == 1:  print "x =", x  else:  print "x =", x# 代码缩进  x = x + 1# 代码缩进  print "x =", x 第3行没有缩进代码,python不能识别出代码的层次关系,python误认为if x == 1:语句后面没有代码块。代码运行后输出如下错误信息: IndentationError: expected an indented block 注意如果缩进的代码前只有一个空格或几个制表符也是符合语法要求的,但是不推荐使用这种写法。最佳的方式是编码前统一代码的书写规则,所有代码前的空格数保持一致,最好使用4个空格缩进。
每行代码缩进的情况不同,代码执行的结果也不同。例如,在【例2-6】中,else子句包含的两条语句都采用了代码缩进的格式,这两条语句组成了一个代码块。
【例2-8】把【例2-6】中的代码修改为如下的内容,则变量x的值将有所变化。
x = 1 if x == 1:  print "x =", x# 代码缩进  else:  print "x =", x# 代码缩进  x = x + 1 print "x =", x 第6行代码与第1行代码处于同一个层次,是主程序必须执行的的代码,因此变量x的值为2。
第7行代码的输出结果:
x = 2 注意当程序出现问题时,程序员首先要检查代码的书写格式,看是否因为代码缩进的问题导致了不期望的计算结果。
2.2.3 模块导入的规范
模块是类或函数的集合,用于实现某个功能。模块的导入和Java中包的导入的概念很相似,都使用import语句。在Python中,如果需要在程序中调用标准库或其他第三方库的类时,需要先使用import或from...import...语句导入相关的模块。
1.import语句
【例2-9】演示使用import语句导入sys模块,并打印相关内容的方法。
# 规范导入方式  import sys  print sys.path  print sys.argv 第2行代码使用import语句导入了sys模块,sys模块是处理系统环境的函数的集合。
第4行代码输出Python环境下的查找路径的集合,Python默认情况下会查找sys.path返回的目录列表。列表是Python内置的数据结构,定义了一组数据,通常用来作为参数或返回值。关于列表的知识请参考第4章的内容。本行代码的输出结果:
\['D:\\\\ developer\\\\ python\\\\   example\\\\ 02\\\\2.2\\\\2.2.3','C:\\\\   WINDOWS\\\\ system32\\\\ python25.zip', ' D:\\\\ developer\\\\ python\\\\ DLLs','D:\\\\   developer [url=]\\\\python[/url] [url=]\\\\lib','D:\\\\[/url] developer  [url=]\\\\[/url] python\\\\ lib\\\\ plat-win',  'D:\\\\ developer\\\\ python\\\\ lib\\\\lib-tk',  'D:\\\\developer [url=]\\\\[/url] python',   'D:\\\\ developer\\\\ python\\\\ lib\\\\   site-packages','D:\\\\developer\\\\ python  [url=]\\\\lib\\\\[/url] site-packages\\\\ win32','D:\\\\   developer\\\\ python\\\\l ib\\\\ site-packages\\\\   win32\\\\ lib',    'D:\\\\developer\\\\ python\\\\ lib\\\\   site-packages\\\\ Pythonwin',    'D:\\\\ developer\\\\ python\\\\lib\\\\   site-packages\\\\ wx-2.8-msw-unicode'\] 第5行代码的sys.argv是存储输入参数的列表。默认情况下,argv自带的参数是文件名。输出结果如下:
\['import.py'\] 2.from...import...语句
首先解释一下命名空间的概念。命名空间是指标识符的上下文。相同名称的标识符可在多条命名空间中定义,命名空间中可以定义任何标识符,并且保证这些标识符不会与任何已有的标识符发生冲突。 
使用from...import...语句导入与import语句导入有所不同,区别是前者只导入模块中的一部分内容,并在当前的命名空间中创建导入对象的引用;而后者在当前程序的命名空间中创建导入模块的引用,从而可以使用“类名.属性”的方式调用。例如import sys后,可以在当前文件中调用sys.path。
【例2-10】使用from...import...语句导入指定内容。实现【例2-9】中代码相同的功能。
#不规范导入方式  from sys import path  from sys import argv  print path  print argv 第5行、第6行代码直接调用path、argv列表的内容,没有模块名的限定,这种写法不够规范。如果程序比较复杂,导入了很多模块,阅读程序的人并不了解path、argv来自哪个模块。而sys.path、sys.argv的写法可以清楚地知道path、argv来自sys模块。
2.2.4 使用空行分隔代码
函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始。
【例2-11】创建一个类A,并在类A中定义funX()和funY()这两个方法。
class A:  def funX(self):  print "funY()" def funY(self):  print "funY()" if __name__ == "__main__":  a = A()  a.funX()  a.funY() 第4行代码插入了一个空行,便于程序员阅读代码,区分方法之间的间隔。
第7行代码也是一个空行。因为下面的if语句是主程序的入口,用于创建类A的对象,并调用其方法。
空行与代码缩进不同,空行并不是Python语法的一部分。书写时不插入空行,Python解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。记住:空行也是程序代码的一部分。
2.2.5 正确的注释
注释是用于说明代码实现的功能、采用的算法、代码的编写者以及代码创建和修改的时间等信息。注释是代码的一部分,注释起到了对代码补充说明的作用。C、C++、Java均采用“//”或“/* */”作为注释的标记,Python的注释方式有所不同。如果只对一行代码注释,使用“#”加若干空格开始,后面是注释的内容,以回车作为注释的结束。如果对一段代码进行注释,也使用“#”,段落之间以一个“#”行分隔。Python一般会忽略“#”行的内容,跳过“#”行执行后面的内容。特殊含义的注释例外,读者可以参考【例4-3】中的代码说明。下面这段代码演示了Python注释的用法。
【例2-12】演示Python注释的使用方法。
# note - show Python's note  # Copyright (C) 2008 bigmarten  #  # This program is free software.   you can redistribute it and/or modify  # it under the terms of the GNU General   Public License as published by  # the Free Software Foundation    #  #############################################  ###########################  #  # Version is 1.0  #  # Its contents are calculate payment。  #  ###############################################  #########################   #规范的变量命名   sumPay = 0# 年薪  bonusOfYear = 2000#年终奖金  monthPay = 1200#月薪  sumPay = bonusOfYear + 12 * monthPay# 年薪=年终奖金+ 12 * 月薪 第1行代码对本文件进行摘要说明。
第2行代码声明了版权信息。
第3行代码是个空行,说明下面将另起一段,注释其他的内容。
第4行到第6行说明程序的许可信息。
第8行到第14行代码说明程序的版本和实现的功能。
第16行开始的代码实现程序的功能,并对每行代码进行单行注释。
Python还有一些特殊的注释,以完成一些特别的功能,如中文注释、程序的跨平台等。
(1)中文注释:如果需要在代码中使用中文注释,必须在Python文件的最前面加上如下注释说明。
# -*- coding: UTF-8 -*- (2)跨平台注释:如果需要使Python程序运行在windows以外的平台,需要在Python文件的最前面加上如下注释说明。
#!/usr/bin/python 此外,注释也用于调试程序。由于文本编辑器不具备调试功能,因此可以使用注释辅助调试。如果一个程序很长,可以把程序分成若干个部分编写。为了更好的调试目前正在编写的程序模块,可以将那些已经编译通过的部分注释掉,或者把多余代码注释掉,以便把主要精力集中在当前编写的逻辑上。
【例2-13】编写一个比较两个数字大小的函数。
def compare Num(num1, num2):  if(num1 > num2):  return str(num1)+" > "+str(num2)  elif(num1 < num2):  return str(num1)+" = "+str(num2)  elif(num1 == num2):  return str(num1)+" = "+str(num2)  else:  return "" 
段代码中的str()实现了数字类型到字符串类型的转换。
编译后显示如下内容:
┄┄python┄┄ 输出完成(耗时: 1 秒) - 正常终止
说明这个函数编译通过,至少在语法上没有任何错误。
【例2-14】接上例。编写【例2-13】中函数的调用程序,以证明【例2-13】中程序的逻辑是否正确。在【例2-13】的代码段后面添加如下代码。
num1 = 2 num2 = 1 print compareNum(num1, num2)  num1 = 2 num2 = 2 print compareNum(num1, num2)  num1 = 1 num2 = 2 print compareNum(num1, num2) 运行程序,发现第3行的输出结果有误:
2 > 1 2 = 2 1 = 2 第1行和第2行的输出结果证明函数compareNum()中num1>num2和num1==num2的判断是正确的,于是想到程序可能是num1<num2的条件判断的逻辑出现了错误。为了证明这一点,注释掉num1<num2的分支判断语句。
【例2-15】接【例2-13】。注释后的compareNum()的代码。
def compareNum(num1, num2):  if(num1 > num2):  return str(num1)+" > "+str(num2)  # elif(num1 < num2):  #return str(num1)+" = "+str(num2)  elif(num1 == num2):  return str(num1)+" = "+str(num2)  else:  return "" 此时,程序编译通过,证明逻辑错误就在num1<num2的分支语句中。仔细检查注释的语句,发现return语句的返回值表达式写错了,其中的“<”误写为了“=”。
【例2-16】接【例2-13】,将【例2-13】中的compareNum()改为正确的写法。
def compareNum(num1, num2):  if(num1 > num2):  return str(num1)+" > "+str(num2)  elif(num1 < num2):  return str(num1)+" < "+str(num2)  elif(num1 == num2):  return str(num1)+" = "+str(num2)  else:  return "" 再次运行整个程序,输出正确结果:
2 > 1 2 = 2 1 < 2 合理的注释方法可以检查程序中的错误。这段代码演示了注释问题语句的做法,并检查这些语句错误的过程。另一种用法是,将正确语句加上注释,单独运行可能有问题的语句,检查语句错误。这两种用法可以根据实际情况分别应用,后者更适合于代码比较长的情况。注释对于程序非常重要,表2-1说明了注释的用法和作用。
表2-1注释的用法及其作用

2.2.6 语句的分隔
在C、Java等语言的语法中规定,必须以分号作为语句结束的标识。Python也支持分号,同样用于一条语句的结束标识。但在Python中分号的作用已经不像C、Java中那么重要了,Python中的分号可以省略,主要通过换行来识别语句的结束。
例如,以下两行代码是等价的:
print "hello world!"
  • print "hello world!";
第1行代码的输出结果:
  • hello world!
第2行代码的输出结果:
  • hello world!
如果要在一行中书写多条句,就必须使用分号分隔每个语句,否则Python无法识别语句之间的间隔:
# 使用分号分隔语句
  • x=1; y=1 ; z=1
第2行代码有3条赋值语句,语句之间需要用分号隔开。如果不隔开语句,Python解释器将不能正确解释,提示语法错误:
  • SyntaxError: invalid syntax
注意分号不是Python推荐使用的符号,Python倾向于使用换行符作为每条语句的分隔,简单直白是Python语法的特点。通常一行只写一条语句,这样便于阅读和理解程序。一行写多条语句的方式是不好的习惯。
Python同样支持多行写一条语句,Python使用“\\”作为换行符。在实践中,一条语句写在多行也是非常常见的。
【例2-17】把SQL语句作为参数传递给函数,由于SQL的语句一般非常长,为了阅读方便,因此需要换行书写。
# 字符串的换行
  • # 写法一 sql = "select id,name \\  
  • from dept \\  where name = 'A'"  
  • print sql  # 写法二
  • sql = "select id,name " \\  "from dept " \\  
  • "where name = 'A'"
  • print sql
写法一只使用了一对双引号,把SQL语句分为select、from、where等3部分分别书写。
第6行代码输出结果:
  • select id,name from dept where name = 'A'
写法二使用了3对双引号,select、from、where分别对应一对双引号。
第11行代码输出结果:
  • select id,name from dept where name = 'A'
第二种写法比第一种写法的可读性更强,可以使用空格和制表符对齐语句,使代码显得更工整。对于简短的语句不推荐换行的写法,这种写法只会造成阅读的复杂性。下面这段程序是不合理的换行写法:
# 一条语句写在多行
  • print \\  
  • "hello world!"
第2行~第3行代码是一个整体,调用print输出“hello world!”,这种情况不适合分行书
2.3 变量和常量
变量是计算机内存中的一块区域,变量可以存储规定范围内的值,而且值可以改变。常量是一块只读的内存区域,常量一旦初始化就不能修改。
2.3.1 变量的命名
变量名由字母、数字或下划线组成。变量名的首字符必须是字母或下划线,首字符之外的字符可以由字母、数字或下划线组成。例如:
# 正确的变量命名
  • var_1 = 1
    print var_1  
  • _var1 = 2
  • print _var1
第2行代码定义了一个名为var_1的变量,该变量的初始值为1。这个变量以字母开头,后面的字符由字母、下划线和数字组成。
第3行代码输出结果:
  • 1
第4行代码定义了一个名为_var1的变量,该变量的初始值为2。这个变量以下划线开头,后面的字符由字母和数字组成。
第5行代码输出结果:
  • 2
【例2-18】演示错误的变量命名方式。
# 错误的变量命名
  • 1_var = 3
    print
    1_var
  • $var = 4
  • print $var
第2行代码定义了一个名为1_var的变量,该变量以数字开头,后面的字符由字母、下划线组成。
第3行代码,变量以数字开头,不符合变量命名的规则。提示如下错误:
  • SyntaxError: invalid syntax
第4行代码定义了一个名为$var的变量,该变量以$符号开头。
第5行代码,变量以$符号开头,不符合变量命名的规则。提示如下错误:
  • SyntaxError: invalid syntax
2.3.2 变量的赋值
Python中的变量不需要声明,变量的赋值操作即是变量声明和定义的过程。每个变量在内存中创建,都包括变量的标识、名称和数据这些信息。例如:
  • x = 1
上面的代码创建了一个变量x,并且赋值为1,如图2-1所示。
[tr][/tr]

Python中一次新的赋值,将创建一个新的变量。即使变量的名称相同,变量的标识并不相同。
【例2-19】演示Python的变量声明以及赋值操作。
# 一次新的赋值操作,将创建一个新的变量
  • x = 1
    print id(x)  
  • x = 2
  • print id(x)
第2行代码定义了一个名为x的变量,该变量的初始值为1。
第3行代码调用函数id,输出变量x的标识。每个变量都有一个内部标识,便于变量的维护和管理。输出结果:
  • 11229424
第4行代码再次定义了一个x的变量,该变量的初始值为2。该变量与前面的变量x并不是同一个变量。
第5行代码输出变量x的标识:
  • 11229412
如果变量没有赋值,Python将认为该变量不存在。例如:
  • print y
运行后,解释器提示:
  • NameError: name 'y' is not defined
在变量y没有赋值的前提下,不能直接输出y的值。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。Python支持对一些变量同时赋值的操作,例如:
# 给多个变量赋值
  • a = (1, 2, 3)  (x, y, z) = a  
  • print "x =", x  print "y =", y  
  • print "z =", z
第2行代码定义了一个序列a,这个序列有3个值:1、2、3。
第3行代码,把序列a的值分别赋值给序列(x, y, z)中的变量x、y、z。
第4行代码输出变量x的值。输出结果:
  • x = 1
第5行代码输出变量y的值。输出结果:
  • y = 2
第6行代码输出变量z的值。输出结果:
  • z = 3
通过序列的装包和拆包操作,实现了同时给多个变量赋值。关于序列的概念请参看第4章的内容 
posted on 2012-03-28 10:52  linyawen  阅读(793)  评论(0编辑  收藏  举报