《Think Python 2e》最新版中文翻译 第二章:变量、表达式和语句 | 数盟社区

第一章链接:http://dataunion.org/24684.html

编程语言最强大的特性之一,是操作变量的能力。变量是指向某个值的名称。

赋值语句

赋值语句(assignment statement)会新建变量,并为这个变量赋值。


 

这个例子进行了三次赋值。 第一次将一个字符串赋给一个叫message的新变量; 第二次将整型数17赋给n; 第三次将ππ的(近似)值赋给pi。

在纸上表示变量的一个常见方法,是写下变量名,并用箭头指向变量的值。 这种图被称为状态图(state diagram),因为它展示了每个变量所处的状态(可以把其看成是变量的心理状态)。 图2-1展示了前面例子的结果。

状态图。

图2-1:状态图。

变量名

程序员通常为变量选择有意义的名字—它们可以记录该变量的用途。

变量名可以任意长。它们可以包括字母和数字,但是不能以数字开头。 使用大写字母是合法的,但是根据惯例,变量名只使用小写字母。

下划线_可以出现在变量名中。 它经常用于有多个单词的变量名,例如my_name或者airspeed_of_unladen_swallow

如果你给了变量一个非法的名称,解释器将抛出一个语法错误:

76trombones是非法的,因为它以数字开头。more@是非法的,因为它包含了一个非法字符@。 但是,class错在哪儿了呢?

原来,class是Python的关键字(keywords)之一。 解释器使用关键字识别程序的结构,它们不能被用作变量名。

Python 3有以下关键词:


 

你没有必要背诵上面的关键词。大部分的开发环境会用不同的颜色区别显示关键词;如果你不小心使用关键词作为变量名,你肯定会发现的。

表达式和语句

表达式(expression)是值、变量和运算符的组合。 值自身也被认为是一个表达式,变量也是,因此下面都是合法的表达式:


 

当你在提示符后输入表达式时,解释器会 ** 计算(evaluate)**该表达式,这就意味着解释器会求它的值。在上面的例子中,n的值是17,n + 25的值是42。

语句(statement)是一个会产生影响的代码单元,例如新建一个变量或显示某个值。


 

第一行是一个赋值语句,将某个值赋给了n。第二行是一个打印语句,在屏幕上显示n的值。

当你输入一个语句后,解释器会执行(execute)这个语句,即按照语句的指令完成操作。一般来说,语句是没有值的。

脚本模式

到目前为止,我们都是在交互模式(interactive mode)下运行Python,即直接与解释器进行交互。交互模式对学习入门很有帮助,但是如果你需要编写很多行代码,使用交互模式就不太方便了。

另一种方法是将代码保存到一个被称为脚本(script)的文件里,然后以脚本模式(script mode)运行解释器并执行脚本。按照惯例,Python脚本文件名的后缀是.py。

如果你知道如何在本地电脑新建并运行脚本,那你可以开始编码了。否则的话,我再次建议使用PythonAnywhere。我在 http://tinyurl.com/thinkpython2e 上贴出了如何以脚本模式运行解释器的指南。

由于Python支持这两种模式,在将代码写入脚本之前,你可以在交互模式下对代码片段进行测试。不过,交互模式和脚本模式之间存在一些差异,可能会让你感到疑惑。

举个例子,如果你把Python当计算器使用,你可能会输入下面这样的代码:


 

第一行将一个值赋给miles,但是并没有产生可见的效果。 第二行是一个表达式,因此解释器计算它并将结果显示出来。 结果告诉我们,一段马拉松大概是42公里。

但是如果你将相同的代码键入一个脚本并且运行它,你得不到任何输出。 在脚本模式下,表达式自身不会产生可见的效果。虽然Python实际上计算了表达式,但是如果你不告诉它要显示结果,它是不会那么做的。

这个行为开始可能有些令人费解。

一个脚本通常包括一系列语句。 如果有多于一条的语句,那么随着语句逐个执行,解释器会逐一显示计算结果。

例如,以下脚本


 

产生的输出结果是


 

赋值语句不产生输出。

在Python解释器中键入以下的语句,看看他们的结果是否符合你的理解:


 

现在将同样的语句写入一个脚本中并执行它。输出结果是什么? 修改脚本,将每个表达式变成打印语句,再次运行它。

运算顺序

当一个表达式中有多于一个运算符时,计算的顺序由运算顺序(order of operations)决定。 对于算数运算符,Python遵循数学里的惯例。 缩写PEMDAS有助于帮助大家记住这些规则:

  • 括号(Parentheses)具有最高的优先级,并且可以强制表达式按你希望的顺序计算。 因为在括号中的表达式首先被计算,那么2 * (3-1)的结果是4,(1+1)**(5-2)的结果是8。 你也可以用括号提高表达式的可读性,如写成(minute * 100) / 60,即使这样并不改变运算的结果。
  • 指数运算(Exponentiation)具有次高的优先级,因此1 + 2**3的结果是9而非27, 2 * 3**2的结果是18而非36。
  • 乘法(Multiplication)和除法(Division)有相同的优先级, 比加法(Addition)和减法(Subtraction)高,加法和减法也具有相同的优先级。 因此2*3-1是5而非4,6+4/2是8而非5。
  • 具有相同优先级的运算符按照从左到右的顺序进行计算(除了指数运算)。 因此表达式degrees / 2 * pi中,除法先运算,然后结果被乘以pi。 为了被2π除,你可以使用括号,或者写成degrees / 2 / pi。

我不会费力去记住这些运算符的优先级规则。如果看完表达式后分不出优先级,我会使用括号使计算顺序变得更明显。

字符串运算

一般来讲,你不能对字符串执行数学运算,即使字符串看起来很像数字, 因此下面这些表达式是非法的:


 

但有两个例外,+ 和 *。

加号运算符 + 可用于 字符串拼接(string concatenation),也就是将字符串首尾相连起来。例如:


 

乘法运算符* 也可应用于字符串;它执行重复运算。 例如,'Spam'*3的结果是'SpamSpamSpam'。 如果其中一个运算数是字符串,则另外一个必须是整型数。

+和*的这个用法,类比加法和乘法也讲得通。 就像4*3与4+4+4等价一样, 我们也会期望'Spam'*3'Spam'+'Spam'+'Spam'等价,而事实上的确如此。 另一方面,字符串拼接和重复与整数的加法和乘法也有很大的不同。 你能想出来一个加法具有而字符串拼接不具有的特性么?

注释

随着程序变得越来越大,越来越复杂,它们的可读性也越来越差。 形式语言是稠密的,通常很难在读一段代码后,说出其做什么或者为什么这样做。

因此,在你的程序中用自然语言做笔记,解释程序做什么通常是比较好的办法。 这些标注被称为注释(comments),以#符号开始。


 

此例中,注释独立一行。你也可以将注释放在行尾:


 

从#开始到行尾的所有内容都会被解释器忽略—其对程序执行没有影响。

在注释中记录代码不明显的特征,是最有帮助的。 假设读者能够读懂代码做了什么是合理的; 但是解释代码为什么这么做则更有用。

下面这个注释只是重复了代码,没有什么用:

下面的注释包括了代码中没有的有用信息:

好的变量名能够减少对注释的需求,但是长变量名使得表达式很难读, 因此这里有个平衡问题。

调试

程序中可能会出现下面三种错误:语法错误(syntax error)、运行时错误(runtime error)和语义错误(semantic error)。我们如果能够分辨出三者区别,有助于快速追踪这些错误。

语法错误:

语法指的是程序的结构及其背后的规则。例如,括号必须要成对出现,所以(1 + 2)是合法的,但是8)则是一个 语法错误

如果你的程序中存在一个语法错误,Python会显示一条错误信息,然后退出运行。你无法顺利运行程序。在你编程生涯的头几周里,你可能会花大量时间追踪语法错误。随着你的经验不断积累,犯的语法错误会越来越少,发现错误的速度也会更快。

运行时错误:

第二种错误类型是运行时错误,这么称呼是因为这类错误只有在程序开始运行后才会出现。这类错误也被称为 异常(exception),因为它们的出现通常说明发生了某些特别的(而且不好的)事情。

在前几章提供的简单程序中,你很少会碰到运行时错误,所以你可能需要一段时间才会接触到这种错误。

语义错误:

第三类错误是“语义”错误,即与程序的意思的有关。如果你的程序中有语义错误,程序在运行时不会产生错误信息,但是不会返回正确的结果。它会返回另外的结果。严格来说,它是按照你的指令在运行。

识别语义错误可能是棘手的,因为这需要你反过来思考,通过观察程序的输出来搞清楚它在做什么。

术语表

变量:
变量是指向某个值的名称。
赋值语句:
将某个值赋给变量的语句。
状态图:
变量及其所指的值的图形化表示。
关键字:
关键字是用于解析程序的;你不能使用if、def和while这样的关键词作为变量名。
运算数(operand):
运算符所操作的值之一。
表达式:
变量、运算符和值的组合,代表一个单一的结果。
计算(evaluate):
通过执行运算以简化表达式,从而得出一个单一的值。
语句:
代表一个命令或行为的一段代码。目前为止我们接触的语句有赋值语句和打印语句。
执行:
运行一个语句,并按照语句的指令操作。
交互式模式:
通过在提示符中输入代码,使用Python解释器的一种方式。
脚本模式:
使用Python解释器从脚本中读取代码,并运行脚本的方式。
脚本:
保存在文件中的程序。
运算顺序:
有关多个运算符和运算数时计算顺序的规则。
拼接:
将两个运算数首尾相连。
注释:
程序中提供给其他程序员(任何阅读源代码的人)阅读的信息,对程序的执行没有影响。
语法错误:
使得程序无法进行解析(因此无法进行解释)的错误。
异常:
只有在程序运行时才发现的错误。
语义:
程序中表达的意思。
语义错误:
使得程序偏离程序员原本期望的错误。

练习题

习题 2-1

和上一章一样,我还是要建议大家在学习新特性之后,在交互模式下充分试验,故意犯一些错误,看看到底会出什么问题。

  • 我们已经知道 n = 42 是合法的。那么 42 = n 呢?
  • x = y = 1 又合法吗?
  • 在某些编程语言中,每个语句都是以分号 结束的。如果你在一个Python语句后也以分号结尾,会发生什么?
  • 如果在语句最后带上句号呢?
  • 在数学记法中,你可以将 xxyy 像这样相乘:xyxy。如果你在Python中也这么写的话,会发生什么?

习题 2-2

继续练习将Python解释器当做计算器使用:

  1. 半径为rr的球体积是43πr343πr3。 半径为5的球体积是多少?

  2. 假设一本书的零售价是$24.95,但书店有40%的折扣。运费则是第一本$3,以后每本75美分。 购买60本的总价是多少?

  3. 如果我上午6:52离开家, 以放松跑(easy pace)的速度跑1英里(每英里8:15,即每英里耗时8分15秒),再以 节奏跑(tempo)的速度跑3英里(每英里7:12,即每英里耗时7分12秒),之后又以放松跑的速度跑1英里,我什么时候回到家吃早饭?

    译者注:配速(pace)是在马拉松运动的训练中常使用的一个概念,配速是速度的一种,是每公里所需要的时间。配速=时间/距离。Tempo run一般被翻译成「节奏跑」或「乳酸门槛跑」,是指以比10K或5K比赛速度稍慢(每公里大约慢10-15秒)的速度进行训练,或者以平时15K-半程的配速来跑。参考:https://www.zhihu.com/question/22237002

贡献者

  1. 翻译:@bingjin
  2. 校对:@bingjin
  3. 参考:@carfly
注:转载文章均来自于公开网络,仅供学习使用,不会用于任何商业用途,如果侵犯到原作者的权益,请您与我们联系删除或者授权事宜,联系邮箱:contact@dataunion.org。转载数盟网站文章请注明原文章作者,否则产生的任何版权纠纷与数盟无关。
期待你一针见血的评论,Come on!

不用想啦,马上 "登录"  发表自已的想法.