编程语言最强大的特性之一,是操作变量的能力。变量是指向某个值的名称。
1.赋值语句 #
赋值语句(assignment statement)会新建变量,并为这个变量赋值。
>>> message = 'And now for something completely different' >>> n = 17 >>> pi = 3.141592653589793
这个例子进行了三次赋值。 第一次将一个字符串赋给一个叫message的新变量; 第二次将整型数17赋给n; 第三次将ππ的(近似)值赋给pi。
在纸上表示变量的一个常见方法,是写下变量名,并用箭头指向变量的值。 这种图被称为状态图(state diagram),因为它展示了每个变量所处的状态(可以把其看成是变量的心理状态)。 图2-1展示了前面例子的结果。
图2-1:状态图。
2.变量名 #
程序员通常为变量选择有意义的名字—它们可以记录该变量的用途。
变量名可以任意长。它们可以包括字母和数字,但是不能以数字开头。 使用大写字母是合法的,但是根据惯例,变量名只使用小写字母。
下划线_
可以出现在变量名中。 它经常用于有多个单词的变量名,例如my_name
或者airspeed_of_unladen_swallow
。
如果你给了变量一个非法的名称,解释器将抛出一个语法错误:
>>> 76trombones = 'big parade' SyntaxError: invalid syntax >>> more@ = 1000000 SyntaxError: invalid syntax >>> class = 'Advanced Theoretical Zymurgy' SyntaxError: invalid syntax
76trombones是非法的,因为它以数字开头。more@是非法的,因为它包含了一个非法字符@。 但是,class错在哪儿了呢?
原来,class是Python的关键字(keywords)之一。 解释器使用关键字识别程序的结构,它们不能被用作变量名。
Python 3有以下关键词:
False | class | finally | is | return |
None | continue | for | lambda | try |
True | def | from | nonlocal | while |
and | del | global | not | with |
as | elif | if | or | yield |
assert | else | import | pass | |
break | except | in | raise |
你没有必要背诵上面的关键词。大部分的开发环境会用不同的颜色区别显示关键词;如果你不小心使用关键词作为变量名,你肯定会发现的。
3.表达式和语句 #
表达式(expression)是值、变量和运算符的组合。 值自身也被认为是一个表达式,变量也是,因此下面都是合法的表达式:
>>> 42 42 >>> n 17 >>> n + 25 42
当你在提示符后输入表达式时,解释器会 ** 计算(evaluate)**该表达式,这就意味着解释器会求它的值。在上面的例子中,n的值是17,n + 25的值是42。
语句(statement)是一个会产生影响的代码单元,例如新建一个变量或显示某个值。
>>> n = 17 >>> print(n)
第一行是一个赋值语句,将某个值赋给了n。第二行是一个打印语句,在屏幕上显示n的值。
当你输入一个语句后,解释器会执行(execute)这个语句,即按照语句的指令完成操作。一般来说,语句是没有值的。
4.脚本模式 #
到目前为止,我们都是在交互模式(interactive mode)下运行Python,即直接与解释器进行交互。交互模式对学习入门很有帮助,但是如果你需要编写很多行代码,使用交互模式就不太方便了。
另一种方法是将代码保存到一个被称为脚本(script)的文件里,然后以脚本模式(script mode)运行解释器并执行脚本。按照惯例,Python脚本文件名的后缀是.py。
由于Python支持这两种模式,在将代码写入脚本之前,你可以在交互模式下对代码片段进行测试。不过,交互模式和脚本模式之间存在一些差异,可能会让你感到疑惑。
举个例子,如果你把Python当计算器使用,你可能会输入下面这样的代码:
>>> miles = 26.2 >>> miles * 1.61 42.182
第一行将一个值赋给miles,但是并没有产生可见的效果。 第二行是一个表达式,因此解释器计算它并将结果显示出来。 结果告诉我们,一段马拉松大概是42公里。
但是如果你将相同的代码键入一个脚本并且运行它,你得不到任何输出。 在脚本模式下,表达式自身不会产生可见的效果。虽然Python实际上计算了表达式,但是如果你不告诉它要显示结果,它是不会那么做的。
miles = 26.2 print(miles * 1.61)
这个行为开始可能有些令人费解。
一个脚本通常包括一系列语句。 如果有多于一条的语句,那么随着语句逐个执行,解释器会逐一显示计算结果。
例如,以下脚本
print(1) x = 2 print(x)
产生的输出结果是
1 2
赋值语句不产生输出。
在Python解释器中键入以下的语句,看看他们的结果是否符合你的理解:
5 x = 5 x + 1
现在将同样的语句写入一个脚本中并执行它。输出结果是什么? 修改脚本,将每个表达式变成打印语句,再次运行它。
5.运算顺序 #
当一个表达式中有多于一个运算符时,计算的顺序由运算顺序(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π2π除,你可以使用括号,或者写成degrees / 2 / pi。
简单地来讲就是:括号>指数运算>乘法=除法>加法=减法
我不会费力去记住这些运算符的优先级规则。如果看完表达式后分不出优先级,我会使用括号使计算顺序变得更明显。
6.字符串运算 #
一般来讲,你不能对字符串执行数学运算,即使字符串看起来很像数字, 因此下面这些表达式是非法的:
'2'-'1' 'eggs'/'easy' 'third'*'a charm'
但有两个例外,+ 和 *。
加号运算符 + 可用于 字符串拼接(string concatenation),也就是将字符串首尾相连起来。例如:
>>> first = 'throat' >>> second = 'warbler' >>> first + second throatwarbler
乘法运算符* 也可应用于字符串;它执行重复运算。 例如,'Spam'*3
的结果是'SpamSpamSpam'
。 如果其中一个运算数是字符串,则另外一个必须是整型数。
+和*的这个用法,类比加法和乘法也讲得通。 就像4*3与4+4+4等价一样, 我们也会期望'Spam'*3
和'Spam'+'Spam'+'Spam'
等价,而事实上的确如此。 另一方面,字符串拼接和重复与整数的加法和乘法也有很大的不同。 你能想出来一个加法具有而字符串拼接不具有的特性么?
7.注释 #
随着程序变得越来越大,越来越复杂,它们的可读性也越来越差。 形式语言是稠密的,通常很难在读一段代码后,说出其做什么或者为什么这样做。
因此,在你的程序中用自然语言做笔记,解释程序做什么通常是比较好的办法。 这些标注被称为注释(comments),以#
符号开始。
# 计算逝去的时间占一小时的比例 percentage = (minute * 100) / 60
此例中,注释独立一行。你也可以将注释放在行尾:
percentage = (minute * 100) / 60 # 逝去时间占一小时的比例
从#开始到行尾的所有内容都会被解释器忽略—其对程序执行没有影响。
在注释中记录代码不明显的特征,是最有帮助的。 假设读者能够读懂代码做了什么是合理的; 但是解释代码为什么这么做则更有用。
下面这个注释只是重复了代码,没有什么用:
v = 5 # 将5赋值给v
下面的注释包括了代码中没有的有用信息:
v = 5 # 加速度,单位:米/秒
好的变量名能够减少对注释的需求,但是长变量名使得表达式很难读, 因此这里有个平衡问题。
8.调试 #
程序中可能会出现下面三种错误:语法错误(syntax error)、运行时错误(runtime error)和语义错误(semantic error)。我们如果能够分辨出三者区别,有助于快速追踪这些错误。语法错误:
语法指的是程序的结构及其背后的规则。例如,括号必须要成对出现,所以(1 + 2)是合法的,但是8)则是一个 语法错误。
如果你的程序中存在一个语法错误,Python会显示一条错误信息,然后退出运行。你无法顺利运行程序。在你编程生涯的头几周里,你可能会花大量时间追踪语法错误。随着你的经验不断积累,犯的语法错误会越来越少,发现错误的速度也会更快。运行时错误:
第二种错误类型是运行时错误,这么称呼是因为这类错误只有在程序开始运行后才会出现。这类错误也被称为 异常(exception),因为它们的出现通常说明发生了某些特别的(而且不好的)事情。
在前几章提供的简单程序中,你很少会碰到运行时错误,所以你可能需要一段时间才会接触到这种错误。语义错误:
第三类错误是“语义”错误,即与程序的意思的有关。如果你的程序中有语义错误,程序在运行时不会产生错误信息,但是不会返回正确的结果。它会返回另外的结果。严格来说,它是按照你的指令在运行。
识别语义错误可能是棘手的,因为这需要你反过来思考,通过观察程序的输出来搞清楚它在做什么。
9.练习题 #
习题 2-1 #
和上一章一样,我还是要建议大家在学习新特性之后,在交互模式下充分试验,故意犯一些错误,看看到底会出什么问题。
- 我们已经知道
n = 42
是合法的。那么42 = n
呢? x = y = 1
又合法吗?- 在某些编程语言中,每个语句都是以分号
;
结束的。如果你在一个Python语句后也以分号结尾,会发生什么? - 如果在语句最后带上句号呢?
- 在数学记法中,你可以将 xx 和 yy 像这样相乘:xyxy。如果你在Python中也这么写的话,会发生什么?
习题 2-2 #
继续练习将Python解释器当做计算器使用:
- 半径为rr的球体积是43πr343πr3。 半径为5的球体积是多少?
- 假设一本书的零售价是$24.95,但书店有40%的折扣。运费则是第一本$3,以后每本75美分。 购买60本的总价是多少?
- 如果我上午6:52离开家, 以放松跑(easy pace)的速度跑1英里(每英里8:15,即每英里耗时8分15秒),再以 节奏跑(tempo)的速度跑3英里(每英里7:12,即每英里耗时7分12秒),之后又以放松跑的速度跑1英里,我什么时候回到家吃早饭?
贡献者 #
推荐阅读 #
bert-serving 模型及源代码 #
Python 教你3分钟用Bert搭建问答搜索引擎 #
【源代码+模型】基于Paddle训练一个98%准确率的抑郁文本预测 #
推荐一个非常优惠的QMT开户渠道 #
有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。
Python实用宝典 (pythondict.com)
关注公众号:Python实用宝典
更多精彩文章等你阅读