跳转到内容

Think Python/变量、表达式和语句

来自维基教科书,开放世界中的开放书籍

值和类型

[edit | edit source]

是程序操作的基本事物之一,例如字母或数字。我们到目前为止见过的值包括1, 2,以及 'Hello, World!'

这些值属于不同的类型2是一个整数,而 'Hello, World!' 是一个字符串,之所以称为字符串,是因为它包含一个字母“字符串”。您可以(以及解释器)通过它们是否包含在引号中来识别字符串。

print 语句也适用于整数。

>>> print (4)
4

如果您不确定某个值的类型,解释器可以告诉您。

>>> type('Hello, World!')
<type 'str'>
>>> type(17)
<type 'int'>

不出所料,字符串属于类型str,而整数属于类型int。不太明显的是,带小数点的数字属于一种称为float的类型,因为这些数字以一种称为浮点数的格式表示。

>>> type(3.2)
<type 'float'>

那么像 '17''3.2' 这样的值呢?它们看起来像数字,但它们包含在像字符串一样的引号中。

>>> type('17')
<type 'str'>
>>> type('3.2')
<type 'str'>

它们是字符串。

当您输入一个大整数时,您可能会倾向于在三位数的组之间使用逗号,例如1,000,000。这在 Python 中不是一个合法的整数,但它是合法的

>>> print 1,000,000
1 0 0

嗯,这完全不是我们预期的!Python 将1,000,000解释为一个以逗号分隔的整数序列,它以空格分隔的形式打印出来。

这是我们见过的第一个语义错误示例:代码在没有产生错误消息的情况下运行,但它并没有做“正确”的事情。

变量

[edit | edit source]

编程语言最强大的功能之一是能够操作变量。变量是引用值的名称。

赋值语句创建新的变量并赋予它们值

>>> message = 'And now for something completely different'
>>> n = 17
>>> pi = 3.1415926535897931

此示例进行了三个赋值。第一个将字符串赋值给一个名为message的新变量;第二个将整数17赋值给n;第三个将 π 的(近似)值赋值给pi.

。在纸上表示变量的一种常见方法是写下名称,并用箭头指向变量的值。这种图被称为状态图,因为它显示了每个变量的状态(将其视为变量的心态)。此图显示了上一个示例的结果

message 'And now for something completely different'
n 17
pi 3.1415926535897931

要显示变量的值,可以使用 print 语句

>>> print n
17
>>> print pi
3.14159265359

变量的类型是它引用的值的类型。

>>> type(message)
<type 'str'>
>>> type(n)
<type 'int'>
>>> type(pi)
<type 'float'>

练习 1

[edit | edit source]

如果您输入一个以零开头的整数,您可能会得到一个令人困惑的错误

>>> zipcode = 02492
                 ^
SyntaxError: invalid token

其他数字似乎可以工作,但结果很奇怪

>>> zipcode = 02132
>>> print zipcode
1114

你能弄清楚发生了什么事吗?提示:打印值 01010010001000

变量名和关键字

[edit | edit source]

程序员通常会选择对变量有意义的名称——它们记录了变量的使用目的。

变量名可以任意长。它们可以包含字母和数字,但必须以字母开头。使用大写字母是合法的,但最好以小写字母开头变量名(您将在后面看到原因)。

下划线字符 (_) 可以出现在名称中。它通常用于包含多个单词的名称,例如 my_nameairspeed_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 的关键字之一。解释器使用关键字来识别程序的结构,它们不能用作变量名。

Python 有 31 个关键字

以及 del from not while
as elif global or with
assert else if pass yield
break except import print
class exec in raise
continue finally is return
def for lambda try

您可能需要将此列表随时备用。如果解释器抱怨您的变量名称之一,而您不知道原因,请查看它是否在此列表中。

如果您在了解 Python 的文本编辑器中编写代码,您可能会发现它可以轻松地让您发现此类关键字冲突,因为它以与普通变量不同的颜色显示关键字。此功能称为语法高亮,大多数程序员都认为它是必不可少的。本书为其示例代码使用语法高亮,因此在以下示例中

ok_variable = 42
yield = 42

您可以看到 yield 被识别为关键字,而不是普通变量,因为它被涂成绿色。

语句

[edit | edit source]

语句是 Python 解释器可以执行的代码单元。我们已经看到了两种语句:print 和赋值。

当您在交互模式下键入语句时,解释器会执行它并显示结果(如果有)。

脚本通常包含一系列语句。如果有多个语句,则结果将随着语句执行而逐一出现。

例如,脚本

print 1
x = 2
print x

产生以下输出

1
2

赋值语句不会产生输出。

运算符和操作数

[edit | edit source]

运算符是代表计算(如加法和乘法)的特殊符号。运算符应用到的值称为操作数

运算符+, -, *, /以及**执行加法、减法、乘法、除法和求幂,如以下示例所示

20+32   hour-1   hour*60+minute   minute/60   5**2   (5+9)*(15-7)

在其他一些语言中,^ 用于求幂,但在 Python 中,它是一个称为异或的按位运算符。我不会在本手册中介绍按位运算符,但您可以在以下地址阅读相关内容:wiki.python.org/moin/BitwiseOperators.

除法运算符可能不会按预期执行

>>> minute = 59
>>> minute/60
0

的值minute是 59,在传统的算术运算中,59 除以 60 等于 0.98333,而不是 0。造成这种差异的原因是 Python 执行的是向下取整除法[1]

当两个操作数都是整数时,结果也是整数;向下取整除法会将小数部分截断,因此在本例中,它向下取整为零。

如果操作数之一是浮点数,Python 将执行浮点数除法,结果为一个float:

>>> minute/60.0
0.98333333333333328

表达式

[edit | edit source]

一个表达式是值、变量和运算符的组合。一个值本身被认为是一个表达式,变量也是,因此以下都是合法表达式(假设变量x已经被赋值了)

17
x
x + 17

如果你在交互模式下输入一个表达式,解释器会计算它并显示结果

>>> 1 + 1
2

但在脚本中,一个表达式本身不会做任何事情!这是初学者常犯的错误。

练习 2

[edit | edit source]

在 Python 解释器中输入以下语句,看看它们做了什么

5
x = 5
x + 1

现在将相同的语句放到脚本中并运行它。输出是什么?通过将每个表达式转换为 print 语句来修改脚本,然后再次运行它。

运算顺序

[edit | edit source]

当一个表达式中出现多个运算符时,运算顺序取决于优先级规则。对于数学运算符,Python 遵循数学惯例。首字母缩略词PEMDAS是记忆规则的一种有用方法

  • Parentheses 具有最高优先级,可用于强制表达式按您想要的顺序计算。由于括号内的表达式首先计算,因此2 * (3-1)为 4,而(1+1)**(5-2)为 8。您也可以使用括号使表达式更易于阅读,例如(minute * 100) / 60,即使它不改变结果。
  • Exponentiation 具有次高优先级,因此2**1+1为 3,而不是 4,并且3*1**3为 3,而不是 27。
  • Multiplication 和 Division 具有相同的优先级,高于 Addition 和 Subtraction,它们也具有相同的优先级。所以2*3-1为 5,而不是 4,并且6+4/2为 8,而不是 5。
  • 具有相同优先级的运算符从左到右计算。因此在表达式degrees / 2 * pi中,除法首先发生,结果乘以pi。要除以 2 π,您可以重新排序操作数或使用括号。

字符串操作

[edit | edit source]

一般来说,您不能对字符串执行数学运算,即使字符串看起来像数字,因此以下操作是非法的

'2'-'1'    'eggs'/'easy'    'third'*'a charm'

the+运算符与字符串一起使用,但它可能不会按预期执行:它执行串联,这意味着将字符串首尾相连。例如

first = 'throat'
second = 'warbler'
print first + second

该程序的输出是throatwarbler.

the*运算符也适用于字符串;它执行重复。例如,’Spam’*3'SpamSpamSpam'。如果操作数之一是字符串,另一个必须是整数。

这种使用+以及*有意义,因为它与加法和乘法类似。就像4*3等同于4+4+4一样,我们希望 'Spam'*3'Spam'+'Spam'+'Spam' 相同,它确实相同。另一方面,字符串串联和重复与整数加法和乘法有一个显著的区别。你能想到加法具有的而字符串串联不具有的属性吗?

注释

[edit | edit source]

随着程序变得越来越大、越来越复杂,它们也越来越难读。形式语言很密集,通常很难查看一段代码并弄清楚它在做什么,或者为什么。

因此,最好在程序中添加注释,以用自然语言解释程序在做什么。这些注释称为注释,它们以#符号开头

# compute the percentage of the hour that has elapsed
percentage = (minute * 100) / 60

在这种情况下,注释出现在一行中。您也可以将注释放在一行的末尾

percentage = (minute * 100) / 60     # percentage of an hour

#到行尾的所有内容都会被忽略——它不会对程序产生任何影响。

注释在记录代码的非明显特征时最有用。可以合理地假设读者可以弄清楚代码做什么;解释为什么更有用。

此注释与代码冗余且无用

v = 5     # assign 5 to v

此注释包含代码中没有的有用信息

v = 5     # velocity in meters/second.

好的变量名可以减少对注释的需要,但过长的名称会使复杂的表达式难以阅读,因此存在权衡。

调试

[edit | edit source]

此时,您最有可能遇到的语法错误是无效的变量名,例如class以及yield,它们是关键字,或者 odd~jobUS$,它们包含无效字符。

如果您在变量名中放一个空格,Python 会认为它是两个没有运算符的操作数

>>> bad name = 5
SyntaxError: invalid syntax

对于语法错误,错误消息并没有多大帮助。最常见的错误消息是SyntaxError: invalid syntax以及SyntaxError: invalid token,它们都不太具有信息量。

您最有可能遇到的运行时错误是“使用前定义”;也就是说,在为变量赋值之前尝试使用它。如果拼错了变量名,就会发生这种情况

>>> principal = 327.68
>>> interest = principle * rate
NameError: name 'principle' is not defined

变量名区分大小写,因此LaTeXlatex.

不同

>>> 1.0 / 2.0 * pi

此时,语义错误最有可能的原因是运算顺序。例如,要计算 1/2 π,您可能会尝试编写

但除法首先发生,因此您将得到 π / 2,它与 1/2 π 不一样!Python 无法知道您想要写什么,因此在这种情况下您不会收到错误消息;您只会得到错误的答案。

词汇表
[edit | edit source]
数据的基本单元之一,例如数字或字符串,程序对其进行操作。
类型int值的类别。到目前为止,我们看到的类型是整数(类型float),浮点数(类型str).
),和字符串(类型
整数
表示整数的类型。
浮点数
表示带小数部分的数字的类型。
字符串
表示字符序列的类型。
变量
指代值的名称。
语句
代表命令或操作的代码部分。到目前为止,我们看到的语句是赋值和 print 语句。
赋值
将值赋给变量的语句。
状态图
一组变量及其所指值的图形表示。
关键字if, def编译器用来解析程序的保留字;您不能使用诸如while
之类的关键字作为变量名。
运算符
表示简单计算的特殊符号,例如加法、乘法或字符串串联。
操作数
运算符作用的值之一。
向下取整除法
将两个数字相除并砍掉小数部分的操作。
表达式
表示单个结果值的变量、运算符和值的组合。
计算
通过按顺序执行运算来简化表达式以生成单个值。
优先级规则
控制包含多个运算符和操作数的表达式计算顺序的规则集。
串联
将两个操作数首尾相连。
注释

程序中的信息,意在供其他程序员(或阅读源代码的任何人)使用,对程序执行没有影响。

练习

[edit | edit source]

练习 3

[edit | edit source]

width = 17
height = 12.0
delimiter = '.'

假设我们执行以下赋值语句

width/2
width/2.0
height/3
1 + 2 * 5
delimiter * 5

对于以下每个表达式,写出表达式的值和类型(表达式的值的类型)。

使用 Python 解释器检查您的答案。

练习 4

[edit | edit source]

  • 半径为 的球体的体积为 4/3 π 。半径为 5 的球体的体积是多少?提示:392.6 是错误的!
  • 假设一本图书的定价为 24.95 美元,但书店可以享受 40% 的折扣。第一本图书的运费为 3 美元,每增加一本图书运费为 75 美分。60 本图书的批发价是多少?
  • 如果我早上 6:52 离开家,以轻松的速度(每英里 8:15)跑 1 英里,然后以中速(每英里 7:12)跑 3 英里,最后再以轻松的速度跑 1 英里,我几点回到家吃早餐?
  1. 在 Python 3.0 中,此除法的结果为 float。新运算符 // 执行整数除法。
华夏公益教科书