个人总结难免疏漏,请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。
本文较简单,5-10分钟即可阅读完成。介绍Python基本过程语句并讨论整体语法模型通用规则(冒号、省略、终止、缩进、其他特殊情况),以及简短示例。暂不介绍函数、类、模块以及异常。
目录
语句
Python的语句
语法-冒号(:)
语法-省略括号
语法-终止语句
语法-缩进
为什么使用缩进语法
语句特殊情况示例
一行多个
横跨多行
代码块规则
简短示例
交互式循环
输入数据做数学运算
检查输入处理错误
try语句处理错误
嵌套三层
语句
语句就是写出来要告诉Python你的程序应该做什么的句子。如果程序是“用一些内容做事情”的话,那么语句就是你指定程序要做哪些事情的方式。
Python程序结构
程序构成:
- 1.程序由模块构成。
- 2.模块包含语句。
- 3.语句包含表达式。
- 4.表达式建立并处理对象。
Python的语法实质上是由语句和表达式组成的。表达式处理对象并嵌套在语句中。语句编码实现程序操作中更大的逻辑关系——它们使用并引导表达式处理对象。
此外,语句还是对象生成的地方(例如,赋值语句中的表达式),有些语句会完全生成新的对象类型(函数、类等)。语句总是存在于模块中的,而模块本身则又是由语句来管理的。
Python的语句
下图表10-1总结了Python的语句集。
这里会介绍Python基本过程语句并讨论整体语法模型。暂不介绍函数、类、模块以及异常,后续其他文章继续介绍。
表10-1中包含了Python 3.0中的语句形式,每部分代码都说明了其具体语法和用途。如下是关于内容的一些说明:
- ·赋值语句以不同的语法形式呈现,基本的、序列的、扩展的等等。
- print在Python 3.0中不是一个保留字,也不是一条语句,而是一个内置的函数调用;由于它几乎总是作为一条表达式语句运行(即,自己单独一行),通常将其看做是一条语句类型。
语法-冒号(:)
所有Python的复合语句(也就是语句中嵌套了语句)都是首行以冒号结尾,首行下一行嵌套的代码往往按缩进的格式书写,如下所示:
冒号是不可或缺的,遗漏掉冒号可能是Python新手最常犯的错误之一。要使得输入冒号变成潜意识里的一种习惯。
语法-省略括号
在Python中,可以省略括号而语句依然会正常工作:
从技术角度来讲,由于每个表达式都可以用括号括起来,在这里的Python程序中加上括号也没什么问题,不会被视为错误的if形式。但是不要这么做,Python方式就是在这类语句中完全省略括号。
>>> x = 1
>>> y = 0>>> if x < y:print('1')
else:print(0)0
>>> if (x < y):print('1')
else:print(0)0
语法-终止语句
Python之中你不需要像类C语言那样用分号终止语句:
在Python中,一般原则是,一行的结束会自动终止出现在该行的语句。就是可以省略分号并且程序会正确工作:
有些方式可以避开这一原则。但是一般来说,绝大多数Python程序代码都是每行一个语句,不需要分号。
语法-缩进
缩进的结束就是代码块的结束,Python中一致地把嵌套块里所有的语句向右缩进相同的距离,Python能够使用语句的实际缩进来确定代码块的开头与结尾:
缩进,是指这里的两个嵌套语句至左侧的所有空白。Python并不在乎怎么缩进(你可以使用空格或制表符)或者缩进多少(你可以使用任意多个空格或是制表符)。
实际上,两个嵌套代码块的缩进可以完全不同。语法规则只不过是给定一个单独的嵌套块中所有语句都必须缩进相同的距离。如果不是这样就会出现语法错误,而程序就无法运行了,直到把缩进修改一致。
为什么使用缩进语法
缩进Python迫使程序员写出统一、整齐并具有可读性程序的主要方式之一。
根据逻辑结构将代码对齐是令程序具有可读性的主要部分,因而具备了重用性和可维护性,对自己和他人都是如此。
即使你之后不使用Python,也应该在任何块结构的语言中对齐代码让程序更具可读性。
在任何代码块结构的语言中,无论是Python还是其他语言,如果嵌套代码块缩进的不一致,它们将很难解释、修改或者再使用,因为代码不再能形象地反应其逻辑含义。可读性是很重要的,缩进又是可读性的主要元素。
举个例子,考虑下面这个C语言的语句:
这个else是属于哪个if的呢?这个else是属于嵌套的if语句[if(y)],即使它看上去很像是属于外层if(x)的。
这种事在Python中是不可能发生的:因为缩进很重要,程序看上去什么样就意味着它将如何运行。考虑一个等价的Python语句:
if x:if y:print('1')
else:print('0')
这个例子里,else垂直对齐的if就是其逻辑上的if(外层的if x)。从某种意义上来说,Python是WYSIWYG语言——所见即所得(what you see is what you get)。
目前几乎每个对程序员友好的文本编辑器都有对Python语法模型的内置支持。
缩进没有绝对的标准:常见的是每层四个空格或一个制表符,但是你想怎么缩进以及缩进多少都由你自己决定。嵌套越深的代码块向右缩进的越厉害,越浅就越靠近前一个块。
不应该在同一段Python代码中混合使用制表符和空格,除非你一贯这么做;在一段给定的代码中,使用制表符或空格,但不要二者都用。
不管用何种语言编写代码,都应该一致地缩进以保持可读性,这一点怎么强调都不过分。
语句特殊情况示例
正如前面提到的,在Python的语法模型中:
·一行的结束就是终止该行语句(没有分号)。
·嵌套语句是代码块并且与实际的缩进相关(没有大括号)。
这些规则几乎涵盖了实际中你会写出或看到的所有Python程序。然而,Python也提供了一些特殊用途的规则来调整语句和嵌套语句的代码块。
一行多个
虽然语句一般都是一行一个,但是Python中也有可能出现某一行挤进多个语句的情况,这时它们由分号隔开:
>>> a = 1; b = 2; print(a+b)
3
这是Python中唯一需要分号的地方——只能把简单语句放在一起作为语句界定符。例如,赋值操作、打印和函数调用。复合语句还是必须出现在自己的行里。
横跨多行
可以让一个语句的范围横跨多行。只需要用一对括号把语句括起来就横跨多行:括号(())、方括号([])或者字典的大括号({})。
任何括在这些符号里的程序代码都可横跨好几行。语句将一直运行,直到Python遇到包含闭合括号的那一行。例如,连续几行列表的常量:
list = [1,2,3]dict = {'a':1,'b':2,'c':3}tuple1 = (1,2,3)
由于程序被括在一对方括号里,Python就会接着运行下一行,直到遇见闭合的方括号为止。花括号包含的字典(以及集合常量、字典解析以及集合解析)也可以用这个方法横跨数行,并且圆括号可以处理元组、函数调用和表达式。
连续行的缩进是无所谓的,尽管常识告诉我们为了让程序具有可读性,那几行也应该对齐。
括号是可以包含一切的——因为任何表达式都可以包含在内,只要插入一个左边括号,你就可以到下一行接着写你的语句。
x = (a + b +c + d)
括号也适用于复合语句。不管你在什么地方需要写一个大型的表达式,只要把它括在括号里,就可以在下一行接着写:
if (a == 1 andb == 2 andc == 3):print('hi')
代码块规则
前面说嵌套代码块中的语句一般都与向右缩进相同的量相关联。
下面的特殊案例,说明复合语句的主体可以出现在Python的首行冒号之后。
if x > y: print(x)
这种可以编辑单行if语句、单行循环等。只有当复合语句本身不包含任何复合语句的时候,才能这样做。只有简单语句可以跟在冒号后面,比如赋值操作、打印、函数调用等。较复杂的语句仍然必须单独放在自己的行里。复合语句的附带部分(例如if的else部分)也必须在自己的行里。
如果将所有语句都分别放在不同的行里并总是将嵌套代码块缩进,那么程序代码会更容易读懂并且便于后期的修改。
简短示例
下面通过简单的实例来说明实际应用中语句语法和语句嵌套相结合的方式,并在其间介绍一些语句。
交互式循环
假设要写个Python程序,要求在控制窗口与用户交互。你需要写一个能够读取用户键盘输入数据的循环并打印每次读取的结果。也就是写一个标准的“读取/计算/打印”的循环程序。
在Python中,这种交互式循环的典型模板代码可能会像这样。
while True:reply = input('输入信息:')if reply == 'stop': breakprint(reply.upper())
这段代码使用了一些概念:
- 利用了Python的while循环,它是Python最通用的循环语句。简单地说,它的组成为:while这个单词,之后跟一个其结果为真或假的表达式,再接一个当顶端测试为真(这时的True看做是永远为真)时不停地迭代的嵌套代码块。
- input内置函数,在这里用于通用控制台输出,它打印可选的参数字符串作为提示,并返回用户输入的回复字符串。
- 利用嵌套代码块特殊规则的单行if语句也在这里出现:if语句体出现在冒号之后的首行,而并不是在首行的下一行缩进。
- Python的break语句用于立即退出循环。也就是完全跳出循环语句而程序会继续循环之后的部分。如果没有这个break退出语句,while循环会因为测试总是真值而永远循环下去。
语句组合实质上是指:从用户那里读取一行并用大写字母打印,直到用户输入"stop"为止。还有一些其他的方式可以编写这样的循环。
要注意的是,在while首行下面嵌套的三行的缩进是相同的。由于它们是以垂直的方式对齐的,所以它们是和while测试相关联的并重复运行的代码块。源文件的结束或是一个缩进较少的语句都能够终止这个循环体块。
这个程序取得的某种程度上的交互:
输入信息:1
1
输入信息:22
22
输入信息:hi
HI
输入信息:stop
Python 2.6或之前的版本应该使用raw_input而不是input,并且你可以在print语句中省略外围的圆括号。
输入数据做数学运算
现在想对数值的输入做些数学运算。例如,求平方。
由于用户输入的是文本信息,需要转为整数,用int()
>>> reply = '20'
>>> reply ** 2
Traceback (most recent call last):File "<pyshell#28>", line 1, in <module>reply ** 2
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'>>> int(reply) ** 2
400
现在重新编写循环来执行必要的数学运算。
while True:reply = input('输入信息:')if reply == 'stop': breakprint(int(reply) ** 2)
print('bye')
像以前一样,这个脚本用了一个单行if语句在"stop"处退出,但是也能够转换输入来进行需要的数学运算。
这个版本在底端加了一条结束信息。最后一行的print语句不像嵌套代码块那样缩进,不会看做是循环体的一部分,只能退出循环之后运行一次。
输入信息:2
4
输入信息:10
100
输入信息:stop
bye
检查输入处理错误
上面输入的是数字,如果输入的是非数字呢?
输入信息:r
Traceback (most recent call last):File "<pyshell#37>", line 4, in <module>print(int(reply) ** 2)
ValueError: invalid literal for int() with base 10: 'r'
内置int函数会发生异常。如果想要我们的脚本够健全,可以事先用字符串对象的isdigit方法检查字符串的内容。
>>> s = '123'
>>> t = 'xx'
>>> s.isdigit(),t.isdigit()
(True, False)
下面这个新版本的交互式脚本使用全方位的if语句来避免错误导致的异常。
while True:reply = input('输入信息:')if reply == 'stop':breakelif not reply.isdigit():print('输入错误,请输入数字')else:print(int(reply) ** 2)print('bye')
完整形式的构成是:if这个关键字后面接测试以及相配的代码块,一个或多个选用的elif(else if)测试以及代码块,以及一个选用的else部分和末尾的一个相配的代码块来作为默认行为。
Python会执行首次测试为真所相配的代码块,按照由上至下的顺序,如果所有测试都是假,就执行else部分。
运行新脚本时,程序会在错误发生前捕捉它,然后打印出(虽然不灵活)错误消息来进行说明。
输入信息:3
9
输入信息:r
输入错误,请输入数字
输入信息:1
1
输入信息:stop
bye
try语句处理错误
在Python中,处理错误最通用的方式是使用try语句,用它来捕捉并完全复原错误。这里不深入,后续文章做详细介绍。
使用try会让有些人认为这要比上一个版本更简单一些:
while True:reply = input('输入信息:')if reply == 'stop':breaktry:num = int(reply)except:print('输入错误,请输入数字')else:print(num ** 2)print('bye')
这个版本的运作方式和上一个版本的相同,这里把刻意进行错误检查的代码,换成了假设转换可工作的代码,然后把无法运作的情况,包含在异常处理器中。
这个try语句的组成是:try关键字后面跟代码主要代码块(我们尝试运行的代码),再跟except部分,给异常处理器代码,再接else部分,如果try部分没有引发异常,就执行这一部分的代码。Python会先执行try部分,然后运行except部分(如果有异常发生)或else部分(如果没有异常发生)。
从语句嵌套来看,try、except以及else这些关键字全都缩进在同一层次上,它们全都被视为单个try语句的一部分。
在Python中,else可出现在if语句中,也可以出现在try语句以及循环中——其缩进会告诉你它属于哪个语句。在这个例子中,try语句从单词try开始,一直到else语句下面缩进的代码结束,因为else和try为相同的缩进层级。
嵌套三层
如果有必要的话,嵌套甚至可以让我们再深入一步。例如,我们可以根据有效输入资料的相对大小,分支到一组替代动作上。
while True:reply = input('输入信息:')if reply == 'stop':breakelif not reply.isdigit():print('输入错误,请输入数字')else:num = int(reply)if num < 20:print('太小')else:print(num ** 2)print('bye')
这个版本包含一个if语句,嵌套在了另一个if语句(嵌套在while循环中)的else子句中。当代码是条件式时,或者像这样重复时,我们只要再往右缩进即可。结果就像前几版那样,不同的是我们现在可以为小于20的数字打印"太小"。
输入信息:20
400
输入信息:19
太小
输入信息:stop
bye