[阅读]Think Python - CH2 Variables, Expressions, and Statements
值和类型
值是计算机最基本的单位,就像字母和数字一样。到现在为止,我们看到的值有,1,2和'Hello, World!'。
这些值的类型不同:2是整型,'Hello, World!'是字符串,这样叫是因为它包含一串字母。你(解释器)可以分辨出字符串,因为它们都是被引号括起来的。
如果你不确定一个值的类型是什么,解释器可以告诉你。
>>> 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里面这不是一个合法的整数,但可以使用:
>>> 1,000,000
(1, 0, 0)
这不是我们想要的值,Python按逗号把1,000,000拆分成整数。这是我们看到的第一个语义错误:代码运行成功,没有错误提示,但结果不正确。
变量
编程语言的强大的特征之一便是可以操作变量。变量是一个指向值的名称。
赋值语句会创建新的变量,并且给他们一个值:
>>> message = 'And now for something completely different' >>> n = 17 >>> pi = 3.1415926535897932
这个例子写了三个赋值语句。第一个赋值语句将一个字符串赋值给变量message;第二个把17赋值给n; 第三个将π的近似值赋值给pi
一般在纸上我们用名称指向变量值的箭头表示变量。这种图叫做状态图,因为它显示了目前变量表示哪个值。
(图略)
变量的类型由变量值决定。
>>> type(message) <type 'str'> >>> type(n) <type 'int'> >>> type(pi) <type 'float'>
练习2-1
如果输入一个以0开头的数字,可能会得到下面的错误:
>>> zipcode = 02492
^
SyntaxError: invalid token
另外一些又可以正常输入,但是结果很奇怪:
>>> zipcode = 02132
>>> zipcode
1114
你能弄清楚怎么回事吗?提示:尝试01,010,0100,和01000.
变量名和关键字
程序员通常会选择有意义的名字来命名变量——变量名能反应这个变量的作用是什么。
变量名可以任意长。可以包含字母和数字,但是必须以字母打头。大写字母是合法的,但最好用小写字母来命名变量(后面会说明原因)。
下划线,_,可以出现在变量名中。它常被用来隔开多个单词,例如 my_name, airapeed_of_unladen_swallow.
如果你写出一个不合法的变量名,解释器会抛出一个语法错误:
>>> 76trombones = 'big parade' SyntaxError: invalid syntax >>> more@ = 1000000 SyntaxError: invalid syntax >>> class = 'Advanced Theoretical Zymurgy' SyntaxError: invalid syntax
76rombones不合法因为它没有以字母打头。more@因为包含非法字符@,但是class为什么也出错了?
原来class是Python关键字中的一个。解释器同过关键字辨别程序结构,不能用它们来做变量名。
Python 2 包含31 个关键字:
and 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 3中,exec不再是关键字,但是nonloacal是一个。
你是否想把这份列表摘抄一份,但解释器报错某个变量名,而你又找不到什么原因的时候,看一下是否在这份名单之中。
操作符合操作数
操作符是一些表示运算的特殊符号,例如加法和减法。操作符运算的值叫做操作数。
运算符 +, -,*,/,和**分别表示加、减、乘、除和幂运算,如下面的例子:
20+32 hour -1 hour*60+minute minute/60 5**2 (5+9)*(15-7)
在一些其他语言中,^用来表示幂运算,但是在Python中,它是一个位运算符,叫做XOR。本书中没有涉及到位运算,但是你可以去维基百科阅读相关资料http://wiki.python.org/moin/BitwiseOperators。
在Python 2 中,除法操作符结果有时候并不是你需要的:
>>> minute = 59
>>> minute/60
0
minute的值是59,通常59除以60我们得到的是0.98333,而非0.出现这种结果的原因是Python采取的是整除。当除数和被除数都是整型时,结果也是一个整型;整除截取了小数部分,所以,上面的例子中,结果只剩下0.
在Python 3 中,上面的结果是个浮点型。新的操作符//表示整除。
如果操作数中的任意一个是浮点数,Python都会运行浮点数除法,并且结果也浮点数:
>>> minute/60.0 0.98333333333333328
表达式和语句
表达式是值、变量和操作符的组合。一个值本身被看做是表达式,变量也是如此,下面这些都是合法的表达式(假设变量x已经被赋值)
17
x
x + 17
语句是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
赋值语句不会输出结果,
练习2-2.
输入下面的语句到Python解释器,看看发生什么:
5 x = 5 x + 1
现在将同样的代码放到一个脚本并运行,输出什么?编辑代码,将每个表达式改写成print语句,再运行试试。
运算顺序
当超过一个运算符出现在同一表达式中,计算顺序取决于优先级。数学运算符遵循原有的优先级,PEMDAS是一个有效的记住优先级的方法。
- Parenthses,括号拥有最高优先级,可以强制表达式按你想要的顺序执行。因为括号内的式子会先执行,所以2*(3-1)的值是4,(1+1)**(5-2)的值是8.你也可以在不改变执行顺序的情况下,使用括号让表达式更易读,例如(minute*100)/60。
- Exponetiation,幂运算的优先级仅次于括号,所以,2**+1的值是3,不是4,3*1**3的值是1,不是27.
- Multiplication and Division,乘法和除法的优先级相同,高于Addition and Subtraction,加法和减法,加法和减法的优先级相同。所以,2*3-1的值是5,不是4,6+4/2的值是8,不是5.
- 运算符的优先级相同时,从左往右执行(除了幂运算)。所以表达式 degree/2*pi,先算除法,结果再乘以pi。如果要除以2pi,可以使用括号,活着使用表达式degree/2/pi。
我没有花很多力气去记住其他操作符的优先级。如果不确定,在表达式中运用括号,让它的优先级明显。
字符串操作符
一般情况下,不可以直接对字符串使用数学操作符,即使在它们看起来是数值的时候,所以,下面的表达式是不合法的:
'2' - '1' 'eggs' / 'easy' 'third' * 'a charm'
操作符+,可以在字符串之间使用,但是它的作用可能不是你想的那样:它的作用的链接,也就是把一个字符创连在另一个后面。如下面的例子:
first = 'throat' second = 'warbler' print first + second
程序输出的结果是 throatwarbler.
操作符*,也可以应用在字符串之间;它表示重复。例如,'Spam' * 3 是'SpamSpamSpam'.如果一个操作数是字符串,另外一个必须是数字。
这里+和*的关系与加法和乘法类似。例如,4*3与4+4+4相等,我们希望'Spam'*3和'Spam' + 'Spam' + 'Spam'也相等,并且它的确如此,另一方面,字符的链接和重复与数值的加法和乘法有一些重要的方面是不一样的。你能想一个加法有,但链接没有的特性吗? //a+b = b+a
注释
随着程序变得越来越大,越来越复杂,也会越来越难阅读。形式语言是晦涩的,很多时候很难阅读一段代码,并且弄明白它们的作用,或者为什么这样写。
因为这个原因,在你的代码添加一些自然语言的说明,说明程序的作用,是一个非常好的习惯。这些说明叫做注释,它们以#打头:
# 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.
好的变量名可以减少注释的必要,但是长的名字却让表达式复杂难读,所以,要权衡利弊。
调试
这里,极有可能出现的,由于定义一个不合法变量名导致的语法错误,例如calss或者yiled,它们是关键字,或者add~job或者UD$,它们包含非法字符。
如果在变量中间放一个空格,Python会认为这是两个没有操作符链接的操作数:
>>> bad name = 5
SyntaxError: invalid syntax
语法错误的提示信息,并不是特别有用。最常见的信息如SyntaxError:invalid syntax或者SyntaxError: invalid token,它们两个都没有提供太多的有用信息。
运行错误你或许还能得到"use before def;"也就是,你使用了一个还没有赋值的变量。它可能发生在你拼错变量名的时候:
>>> principal = 327.68 >>> interest = principle * rate NameError: name 'principle' is not defined
变量名大小写敏感,所以,LaTeX和latex不同。
这里最有可能出现的语义错误是操作符的执行顺序。例如,计算 1/(2pi), 你或许会写成
>>> 1.0 / 2.0 * pi
除法先运算,你会得到pi/2,不同的结果!Python是无法知道你想写的是什么,因此不会有错误提示;只会有一个错误的结果。
词汇表
值
类型
整型
字符串
小数点
变量
状态图
关键字
操作符
操作数
整除
表达式
优先级
链接