1、dPython 入门原著 Guido van Rossum翻译 李东风 第一章 介绍 第二章 解释程序的使用 第三章 基本使用 第四章 流程控制 第五章 Python 数据结构 第六章 模块 第七章 输入输出 第八章 错误与例外 第九章 类 第十章 进一步学习 第一章 介绍脚本语言是类似 DOS 批处理、UNIX shell 程序的语言。脚本语言不需要每次编译再执行,并且在执行中可以很容易地访问正在运行的程序,甚至可以动态地修改正在运行的程序,适用于快速地开发以及完成一些简单的任务。在使用脚本语言时常常需要增的新的功能,但有时因为脚本语言本来就已经很慢、很大、很复杂了而不能实现;或者,所需的功
2、能涉及只能用 C 语言提供的系统调用或其他函数通常所要解决的问题没有重要到必须用 C 语言重写的程度;或者,解决问题需要诸如可变长度字符串等数据类型(如文件名的有序列表),这样的数据类型在脚本语言中十分容易而 C 语言则需要很多工作才能实现;或者,编程者不熟悉 C 语言:这些情况下还是可以使用脚本语言的。在这样的情况下,Python 可能正好适合你的需要。Python 使用简单,但它是一个真正的程序语言,而且比 shell 提供了更多结构和对大型程序的支持。另一方面,它比 C 提供更多的错误检查,它是一个非常高级的语言,内置了各种高级数据结构,如灵活的数组和字典,这些数据结构要用 C 高效实现
3、的话可能要花费你几天的时间。由于 Python 具有更一般的数据结构,它比 Awk 甚至 Perl适用的范围都广,而许多东西在 Python 内至少和在这些语言内一样容易。Python 允许你把程序分解为模块,模块可以在其他 Python 程序中重用。它带有一大批标准模块可以作为你自己的程序的基础或作为学习 Python 编程的例子。系统还提供了关于文件输入输出、系统调用、插座(sockets)的东西,甚至提供了窗口系统(STDWIN)的通用接口。Python 是一个解释性语言,因为不需要编译和连接所以能节省大量的程序开发时间。解释程序可以交互使用,这样可以可以很容易地试验语言的各种特色,写只
4、用一次的程序,或在从底向上程序开发中测试函数。它也是一个方便的计算器。Python 允许你写出非常严谨而且可读的程序。用 Python 写的程序通常都比相应的 C 程序要短,因为如下几个理由: 高级的数据结构允许你用一个语句表达复杂的操作; 复合语句是靠缩进而不是用表示开始和结束的括号; 不需要变量声明或参量声明。 Python 是可扩充的:如果你会用 C 语言编程就很容易为解释程序增加新的内置函数或模块,这样可以以最快速度执行关键操作,或把 Python 程序和只能以二进制码提供的库(如不同厂商提供的图形库)连接起来。当你变得确实很在行时你可以把 Python 解释器与用 C 写的应用相连接
5、,把它作为该应用的扩展或命令语言。 Python 的命名是由 BBC 的“Monty Pythons Flying Circus”节目而得,与蟒蛇没有什么关系。第二章 解释程序的使用在命令行键入 python或在 Windows 环境下双击相应的图标可以进入 Python 的解释程序。如果要运行储存在文件中的 Python 程序,可以用 python 文件名的形式。 进入解释程序的环境后,解释程序称为处于交互状态。在这种状态下系统用 主提示 提示输入下一个命令,这一般是三个大于号(),如果需要续行系统用 次提示 提示输入,缺省为三个小数点(.)。在主提示下键入文件尾符号(在UNIX 中为 Co
6、ntrol-D,在 DOS 或 Windows 中为 Control-Z)可以正常退出解释程序。Python 解释程序的有些版本支持命令行编辑和命令历史,使用用 Emacs 或vi 的键组合。 第三章 基本使用下面我们用例子来介绍 Python 的基本用法。在例子中,用户输入和系统输出靠有没有提示(和.)来分别。如果要试这些例子的话,需要键入提示后的所有命令,例子中没有提示的行是系统的输出。注意只有次提示的行意味着需要键入一个空行,这用于结束多行命令。3.1 用 Python 作计算器使用启动解释程序,等待主提示出现。解释程序可以作为计算器使用。键入一个表达式,解释程序就可以输出结果。表达式的
7、写法很直观:+,-,*,/, %, *等算符的作用和其它大多数语言(如 Pascal 或 C)没什么差别,括号可以用来组合。例如: 2+24 # 这是一个注释. 2+24 2+2 # 和代码在同一行的注释4 (50-5*6)/45 # 整数除法得下面的整数. 7/32 7/-3-3和 C 中一样,等于号用来给变量赋值,赋值的结果不显示: width = 20 height = 5*9 width * height900可以同时给几个变量赋同一个值: x = y = z = 0 # 把 x, y 和 z 赋零 x0 y0 z0Python 完全支持浮点数,混合类型的运算会把整数先转换成浮点数:
8、4 * 2.5 / 3.33.0303030303 7.0 / 23.5Python 也提供了复数,方法是用 j 和 J 作为虚数单位,如 1+1j,3.14e-10j,等等。 3.2. 字符串Python 除处理数字外还可以处理字符串,字符串用单撇号或双撇号包裹: spam eggsspam eggs doesnt“doesnt“ “doesnt“doesnt“ “Yes,“ he said.“Yes,“ he said. “Yes,“ he said.“Yes,“ he said. “Isnt,“ she said.“Isnt,“ she said.字符串输出格式与输入的样子相同,都是用撇
9、号包裹,撇号和其它特殊字符用用反斜杠转义。如果字符串中有单撇号而没有双撇号则用双撇号包裹,否则应该用单撇号包裹。后面要介绍的 print 语句可以不带撇号或转义输出字符串。字符串可以用+号连接起来,用*号重复: word = Help + A wordHelpA 字符串可以象在 C 中那样用下标索引,字符串的第一个字符下标为 0。 Python 没有单独的字符数据类型,一个字符就是长度为一的字符串。象在 Icon语言中那样,可以用片段(slice)记号来指定子串,片段即用冒号隔开的两个下标。 word4A word0:2He word2:4lp片段有很好的缺省值:第一下标省略时缺省为零,第二下
10、标省略时缺省为字符串的长度。 word:2 # 前两个字符He word2: # 除前两个字符串外的部分lpA注意 s:i + si: 等于 s 是片段运算的一个有用的恒等式。 word:2 + word2:HelpA word:3 + word3:HelpA不合理的片段下标可以很好地得到解释:过大的下标被换成字符串长度,上界小于下界时返回空串。 word1:100elpA word10: word2:1下标允许为负数,这时从右向左数。例如: word-1 # 最后一个字符A word-2 # 倒数第二个字符p word-2: # 最后两个字符pA word:-2 # 除最后两个字符外的部分H
11、el但要注意的是 -0 实际还是 0,所以它不会从右向左数! word-0 # (因为 -0 等于 0)H超出范围的片段下标被截断,但在非片段的情况下不要这样: word-100:HelpA word-10 # 错误Traceback (innermost last):File “, line 1IndexError: string index out of range记住片段意义的最好方法是把下标看成是字符 之间的点,第一个字符的左边界号码为 0。有 n 个字符的字符串的最后一个字符的右边界下标为 n,例如:+-+-+-+-+-+ | H | e | l | p | A |+-+-+-+-+
12、-+ 0 1 2 3 4 5 -5 -4 -3 -2 -1第一行数字给出字符串中下标 0 到 5 的位置,第二行给出相应的负下标。从 i到 j 的片段由在边界 i 和 j 之间的字符组成。对于非负下标,如果下标都在界内,则片段的长度为下标的差。例如,word1:3 的长度为 2。内置函数 len()返回字符串的长度: s = supercalifragilisticexpialidocious len(s)34多行的长字符串也可以用行尾反斜杠续行,续行的行首空白不被忽略,如hello = “This is a rather long string containingnseveral line
13、s of text just as you would do in C.nNote that whitespace at the beginning of the line issignificant.n“print hello结果为This is a rather long string containingseveral lines of text just as you would do in C.Note that whitespace at the beginning of the line is significant.对于特别长的字符串(比如包含说明的几段文字),如果用上面的方式
14、每行都用n结尾是很麻烦的,特别是这样无法用象 Emacs 这样的功能强大的编辑器重新编排。对这种情况,可以使用三重撇号,例如hello = “This string is bounded by triple double quotes (3 times “).Unescaped newlines in the string are retained, though it is still possiblento use all normal escape sequences.Whitespace at the beginning of a line issignificant. If you
15、need to include three opening quotesyou have to escape at least one of them, e.g. “.This string ends in a newline.“三重撇号字符串也可以用三个单撇号,没有任何语义差别。 多行的字符串常量可以直接连接起来,字符串常量之间用空格分隔则在编译时可以自动连接起来,这样可以把一个长字符串连接起来而不需要牺牲缩进对齐或性能,不象用加号连接需要运算,也不象字符串串内的换行其行首空格需要保持。3.3 列表Python 中有几种复合数据类型,用来把其它值组合到一起。其中最灵活的是列表,可以写成在方括
16、号之间用逗号隔开的若干值(项)。列表的项不必取同一类型。 a = spam, eggs, 100, 1234 aspam, eggs, 100, 1234象字符串下标那样,列表下标从 0 开始,列表可以取片段,可以连接,等等: a0spam a31234 a-2100 a1:-1eggs, 100 a:2 + bacon, 2*2spam, eggs, bacon, 4 3*a:3 + Boe!spam, eggs, 100, spam, eggs, 100, spam, eggs, 100, Boe!与字符串不同的是列表是可变的,可以修改列表的每个元素: aspam, eggs, 100,
17、1234 a2 = a2 + 23 aspam, eggs, 123, 1234也可以给一个片段重新赋值,这甚至可以改变表的大小: # 替换若干项:. a0:2 = 1, 12 a1, 12, 123, 1234 # 去掉若干项:. a0:2 = a123, 1234 # 插入若干项:. a1:1 = bletch, xyzzy a123, bletch, xyzzy, 1234 a:0 = a # 在开头插入自身 a123, bletch, xyzzy, 1234, 123, bletch, xyzzy, 1234内置函数也使用于列表: len(a)8可以建立嵌套列表(表的元素也是列表),如
18、: q = 2, 3 p = 1, q, 4 len(p)3 p12, 3 p102 p1.append(xtra) # 列表方法 p1, 2, 3, xtra, 4 q2, 3, xtra注意这个例子中 p1和 q 实际是同一个对象!也就是说它们只不过是同一个东西的两个名字(引用)而已。3.4 编程初步Python 当然不是只能用来把两个数加到一起,它可以完成很复杂的工作。例如,我们可以写出 Fibonacci 序列的开始几个: # Fibonacci 序列:. # 两个元素的和定义下一个. a, b = 0, 1 while b 这个例子介绍了几个新特色。 第一行包含一个多重赋值: 变量
19、a 和 b 同时得到新值 0 和 1。在最后一行又用了多重赋值,我们可以看出赋值时先把右边都算出后再进行赋值。while 循环当循环条件(这里即: b , =, = 和 !=。循环体是缩进的:缩进是 Python 用来组合语句的方式。Python 目前还不能提供智能自动缩进,所以你需要自己为每个缩进行键入制表符或空格。实际使用中你可以用文本编辑程序为 Python 准备复杂的输入,多数文本编辑程序都有自动缩进的功能。在交互输入复合语句时必修附加一个空行以指示复合语句的完成(因为解释程序无法猜到哪是语句的最后一行)。print 语句显示后面的表达式值。这和直接写出表达式不同,它可以显示多个表达式
20、和字符串,而且可以用于程序文件中。显示时字符串没有撇号,各项目之间插入一个空格,所以你可以以精美的格式显示,如: i = 256*256 print The value of i is, iThe value of i is 65536在尾部写一个逗号可以避免最后换行: a, b = 0, 1 while b 注意如果前一行没有结束的话系统在显示提示之前先换行。 Python 还提供了和 C 语言一样的 printf 格式的输出方式,这是用%实现的,左边是格式,如: print The value of 1/7 is approximately %5.3f. % 0.142857The val
21、ue of 1/7 is approximately 0.143.如果有多个需要输出的项百分号右边的项可以是一个序组,如 print “Name: %-10s Age: %3d“ % (“White“, 31)Name: White Age: 31第四章 流程控制前面我们已经见到了如何由用 while 结构控制流程运行。这一章我们介绍更多的控制结构。Python 具有和其它语言类似的控制结构但略有差别。4.1 If 语句If 语句可能是最基本的程序分支语句了。例如: if x # 计算字符串长:. a = cat, window, defenestrate for x in a:. print
22、 x, len(x). cat 3window 6defenestrate 12尽量不要在循环体内修改用来控制循环的序列(当然,只有可变的序列类型如列表才有可能被修改),这样程序可能会出问题。如果需要这样,比如说要复制某些项,可以用序列的副本来控制循环。片段记号让你很容易生成副本: for x in a: # 生成整个列表的片段副本. if len(x) 6: a.insert(0, x). adefenestrate, cat, window, defenestrate结果是把列表中长度超过 6 个字符的字符串插入到列表开头。 4.3 range() 函数如果确实需要对一列数字进行循环的话,
23、可以使用内置函数 range()。它生成包含数字序列的列表,如: range(10)0, 1, 2, 3, 4, 5, 6, 7, 8, 9注意给出的终点永远不出现在生成的列表中,range(10)生成一个十个数的列表,恰好是长度为 10 的序列的合法下标的各个值。也可以指定不同的起始点,或者指定不同的间隔(甚至负数): range(5, 10)5, 6, 7, 8, 9 range(0, 10, 3)0, 3, 6, 9 range(-10, -100, -30)-10, -40, -70为了对序列的下标进行循环,如下联合使用 range() 和 len(): a = Mary, had,
24、a, little, lamb for i in range(len(a):. print i, ai. 0 Mary1 had2 a3 little4 lamb4.4 break 语句,continue 语句和循环中的 else 子句如同 C 语言一样,break 语句跳出其所处的最内层的 for 或 while 循环,continue 语句继续下一循环步。循环语句还可以带一个 else 子句,当循环正常结束时执行其内容,但如果循环是用 break 语句跳出的则不执行其内容。下例说明了这种用法,此例求素数: for n in range(2, 10):. for x in range(2,
25、n):. if n % x = 0:. print n, equals, x, *, n/x. break. else:. print n, is a prime number. 2 is a prime number3 is a prime number4 equals 2 * 25 is a prime number6 equals 2 * 37 is a prime number8 equals 2 * 49 equals 3 * 34.5 pass 语句pass 语句不执行任何操作,当语法要求一个语句而程序不需要执行操作时就用此语句。例如: while 1:. pass # 等待键盘中
26、断.4.6 函数定义我们可以定义一个函数用来计算某一界限以下的所有 Fibonacci 序列值: def fib(n): # 写出 n 以下的所有 Fibonacci 序列值. a, b = 0, 1. while b # 调用刚刚定义的函数:. fib(2000)1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597其中关键字 def 开始一个函数定义,其后应该是函数名,括号内的形参表,以冒号结束。构成函数体的各语句从下一行开始,用一个制表符缩进。函数的第一个语句可以是一个字符串,如果是的话,这个字符串就是函数的文档字符串,简称为 docstr
27、ing。有一些工具可以利用文档字符串自动生成可打印的文档,或者让用户交互地浏览代码,所以在自己编程时加入文档字符串是一个好习惯,应该养成这样的习惯。函数在执行时对局部变量引入一个新的符号表。函数中的变量赋值都存入局部符号表;引用变量时变量名先从局部符号表中查找,然后在全局符号表中查找,最后从内置的名字中查找。因此,在函数中不能直接对全局变量赋值(除非用了 global 语句来说明),但可以引用全局变量的值。函数调用的实参被引入函数的局部符号表,即函数的参数是按值调用的。函数再调用其它函数时为该函数生成一个新的符号表。但是严格地说,函数的调用是按引用调用的,因为如果参数是一个可变类型如列表的话在
28、函数中改变形参的内容将导致实参的内容被改变(不改变的是实参名字的绑定关系)。函数定义把函数名放入当前符号表。函数名的值类型为用户自定义函数,这个值可以赋给另一个名字,从而这个名字也代表相同的函数。这可以作为一般的改名方法: fib f = fib f(100)1 1 2 3 5 8 13 21 34 55 89你可能会说 fib 不是函数而是过程。Python 和 C 一样,过程只是不返回值的函数。实际上,严格地说,过程也返回一个值,只不过是一个很没意思的值。这个值叫做 None(这是一个内置的名字)。解释程序交互运行时如果只需要显示这个值的话就会忽略不显示。如果希望显示的话可以用 print
29、 语句: print fib(0)None也可以写一个函数返回 Fibonacci 序列的数值列表而不是显示这些值: def fib2(n): # 返回直到 n 的 Fibonacci 序列值. result = . a, b = 0, 1. while b f100 = fib2(100) # 调用 f100 # 输出结果1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89这个例子也演示了新的 Python 特色:return 语句从函数中退出并返回一个值。不带返回值的 return 可以从过程中间退出,运行到过程的末尾也可以退出,这两种情况下返回 None。语句 res
30、ult.append(b)调用列表对象 result 的一个方法。方法是“属于”一个对象的函数,引用格式为 obj.methodname,其中 obj 是某个对象(也允许是一个表达式), methodname 是由该对象的类型定义的一个方法的名字。不同的不同的方法。不同类型的方法可以使用相同的名字而不致引起误解。(可以定义自己的对象类型和方法,使用类,本文后面会讨论这个话题)。例子中的append()方法时列表对象的方法,它在列表末尾增加一个新元素。在本例中这等价于“result = result + b”,只是更有效。4.7 函数参数可以定义使用可变个数参数的函数。这样的定义方法有三种,可以
31、联合使用。4.7.1 参数缺省值可以为一个参数或几个参数指定缺省值。这样定义的函数在调用时实参个数可以比定义时少。例如:def ask_ok(prompt, retries=4, complaint=Yes or no, please!):while 1:ok = raw_input(prompt)if ok in (y, ye, yes): return 1if ok in (n, no, nop, nope): return 0retries = retries - 1if retries a = 66.6, 333, 333, 1, 1234.5 print a.count(333),
32、a.count(66.6), a.count(x)2 1 0 a.insert(2, -1) a.append(333) a66.6, 333, -1, 333, 1, 1234.5, 333 a.index(333)1 a.remove(333) a66.6, -1, 333, 1, 1234.5, 333 a.reverse() a333, 1234.5, 1, 333, -1, 66.6 a.sort() a-1, 1, 66.6, 333, 333, 1234.55.1.1 函数程序设计工具Python 中有一些函数程序设计风格的东西,例如前面我们看到的 lambda 形式。关于列表有
33、三个非常有用的内置函数:filter(), map()和 reduce()。“filter(函数, 序列)”返回一个序列(尽可能与原来同类型),序列元素是原序列中由指定的函数筛选出来的那些,筛选规则是“函数(序列元素)=true”。filter()可以用来取出满足条件的子集。例如,为了计算一些素数: def f(x): return x % 2 != 0 and x % 3 != 0. filter(f, range(2, 25)5, 7, 11, 13, 17, 19, 23“map(函数,序列)”对指定序列的每一项调用指定的函数,结果为返回值组成的列表。map() 可以对序列进行隐式循环。
34、例如,要计算三次方,可用: def cube(x): return x*x*x. map(cube, range(1, 11)1, 8, 27, 64, 125, 216, 343, 512, 729, 1000可以有多个序列作为自变量,这时指定的函数必须也有相同个数的自变量,函数从每个序列分别取出对应元素作为自变量进行调用(如果某个序列比其它的短则取出的值是 None)。如果指定的函数是 None,map()把它当成一个返回自己的自变量的恒同函数。在函数用 None 的情况下指定多个序列可以把多个序列搭配起来,比如“map(None, list1, list2)”可以把两个列表组合为一个成对
35、值的列表。见下例: seq = range(8) def square(x): return x*x. map(None, seq, map(square, seq)(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49)“reduce(函数, 序列)”用来进行类似累加这样的操作,这里的函数是一个两个子变量的函数,reduce()先对序列的前两项调用函数得到一个结果,然后对结果和序列下一项调用函数得到一个新结果,如此进行到序列尾部。例如,要计算 1 到 10 的和: def add(x,y): return x+y.
36、reduce(add, range(1, 11)55如果序列中只有一个值则返回这个值,序列为空时会产生例外。可以指定第三个自变量作为初始值。有初始值时对空序列函数将返回初始值,否则函数先对初始值和序列第一项作用,然后对结果和序列下一项作用,如此进行到序列尾。例如: def sum(seq):. def add(x,y): return x+y. return reduce(add, seq, 0). sum(range(1, 11)55 sum()05.2 del 语句上面我们看到,列表的 remove()方法可以从列表中删去某个取值的项,我们还可以用 del 语句来删除指定下标的项。也可以用
37、 del 语句从列表中删除一个片断(前面我们是用给片断赋空列表的办法删除片断的)。例如: a-1, 1, 66.6, 333, 333, 1234.5 del a0 a1, 66.6, 333, 333, 1234.5 del a2:4 a1, 66.6, 1234.5del 也可以用来删除整个变量,例如: del a变量删除以后再引用该变量就会出错(除非又给它赋值了)。后面我们还会看到 del 的其它一些应用。5.3 序表和序列我们看到列表和字符串有许多共同点,例如,下标和片断运算。它们都属于序列数据类型。因为 Python 是一个正在不断发展的语言,以后还可能会加入其它的序列数据类型。现在
38、还有一种标准的序列数据类型,称为序表(tuple)。序表由一系列值用逗号分隔而成,例如: t = 12345, 54321, hello! t012345 t(12345, 54321, hello!) # 序表允许嵌套:. u = t, (1, 2, 3, 4, 5) u(12345, 54321, hello!), (1, 2, 3, 4, 5)输出的序表总是用括号包围,这样可以保证嵌套序表得以正确解释。输入时可以有括号也可以没有括号,当经常是必须有括号(如果序表是一个大表达式的一部分)。序表有许多用处,例如,(x,y)坐标对,数据库中的职工纪录,等等。序表与字符串一样是不可变的:不允许对
39、序表的某一项赋值。生成序表时对 0 项或 1 项的序表有特殊的规定:空序表用一对空括号表示;只有一项的序表用一个之后面跟一个抖好表示(指把这个值放在括号内是不够的)。这样写不够美观,但很有效。例如: empty = () singleton = hello, # len(empty)0 len(singleton)1 singleton(hello,)语句 t = 12345, 54321, hello!是序表打包的一个实例:12345, 54321 和hello!这些值被打包进了一个序表中。相反的操作也是允许的,例如: x, y, z = t这叫做序表解包。序表解包要求等号左边的变量个数等于
40、序表的长度。注意多重赋值只是序表打包和序表解包的联合使用。有时也对列表进行类似操作,即列表解包。只要把各变量写成一个列表就可以进行解包: a = spam, eggs, 100, 1234 a1, a2, a3, a4 = a5.4 字典Python 内置的另一个有用的数据类型是字典。字典在其它语言中有时被称为“关联记忆” 或“关联数组”。字典不象序列,它不是用在一个范围之内的数字下标来索引,而是用键值来索引,键值可以是任何不可变类型。字符串和数值总可以作键值。如果序表只包含字符串、数值或序表则序表也可以作键值使用。列表不能用作键值,因为列表可以用其 append()方法就地改变值。最好把字典
41、看成是一系列未排序的“键值:值”的集合,在同一字典内键值是互不相同的。一对空大括号产生一个空字典:。在大括号内加入用逗号分开的“键值:值”对可以在字典内加入初始的键值和值对,字典在输出时也是这样显示的。对字典的主要操作是以某个键值保存一个值,以及给定键值后查找对应的值。也可以用 del 删除某个键值:值对。如果用一个已有定义的键值保存某个值则原来的植被遗忘。用不存在的键值去查找会出错。字典对象的 keys()方法返回字典中所有键值组成的列表,次序是随机的。需要排序时只要对返回的键值列表使用 sort()方法。为了检查某个键值是否在字典中,使用字典的 has_key() 方法。下面是字典使用的一
42、个简单例子: tel = jack: 4098, sape: 4139 telguido = 4127 telsape: 4139, guido: 4127, jack: 4098 teljack4098 del telsape telirv = 4127 telguido: 4127, irv: 4127, jack: 4098 tel.keys()guido, irv, jack tel.has_key(guido)15.5 条件的进一步讨论在 while 语句和 if 语句中使用的条件除了可以使用比较之外还可以包含其它的运算符。比较运算符“in”和“not in”可以检查一个值是否在一个
43、序列中。运算符“is”和“is not ”比较两个对象是否恰好是同一个对象,这只对象列表这样的可变对象有意义。所有比较运算优先级相同,而比较运算的优先级比所有数值运算优先级低。比较允许连写,例如,a string1, string2, string3 = , Trondheim, Hammer Dance non_null = string1 or string2 or string3 non_nullTrondheim注意 Python 和 C 不同,表达式中不能进行赋值。 5.6 序列与其它类型的比较序列对象可以和其它同序列类型的对象比较。比较使用字典序:先比较最前面两项,如果这两项不同则
44、结果可以确定;如果这两项相同,就比较下面的两项,如此下去,直到有一个序列到头为止。如果某两项本身也是同类型的序列,则进行递归的字典序比较。如果两个序列的所有各项都相等,则这两个序列相等。如果一个序列是另一个序列的一个初始子序列,短的一个是较小的一个。字符串的字典序比较按各个字符的 ASCII 次序进行。下面是一些序列比较的实例:(1, 2, 3) import fibo这不会把模块 fibo 中的函数的名字直接引入当前的符号表,这只是把模块名fibo 引入。可以用模块名来访问其中的函数: fibo.fib(1000)1 1 2 3 5 8 13 21 34 55 89 144 233 377
45、610 987 fibo.fib2(100)1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 fibo._name_fibo如果经常使用某个函数可以给它赋一个局部名字: fib = fibo.fib fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 3776.1 模块的进一步介绍模块除了可以包含函数定义之外也可以包含可执行语句。这些可执行语句用来初始化模块,它们只在模块第一次被导入时执行。每个模块有自己私有的符号表,这个私有符号表对于模块中的所有函数而言却是它们的全局符号表。因此,模块作者可以在模块中使用全局变量而不需担心与模块用户的
46、全局变量冲突。另一方面,如果你有把握的话也可以用访问模块中函数的格式,即 modname.itemname 的方法来修改模块中的全局变量。模块可以导入其它模块。我们通常把所有的导入语句放在模块(或脚本)的开始位置,这不是规定要求的。导入的模块名放入模块的全局符号表中。导入还有另一种用法,可以把模块中的名字直接导入使用者的符号表。例如: from fibo import fib, fib2 fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377这不会把模块名导入使用者的符号表中(例如,上面例子中 fibo 就没有定义)。还有一种办法可以导入一个模块中定义的所
47、有名字: from fibo import * fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377这可以把模块中除了以下划线结尾的所有名字导入。 6.1.1 模块搜索路径在导入名为 spam 的模块时,解释程序先在当前目录中寻找名为“spam.py”的文件,然后从环境变量 PYTHONPATH 所定义的目录列表中寻找。PYTHONPATH 的用法和可执行文件的搜索路径 PATH 用法相同,都是一个目录列表。当PYTHONPATH 未设置的时候,或者文件仍找不到,则搜索继续在安装时设定的缺省路径搜索,在 Unix 中,这通常是“.:/usr/local/lib/python” 。实际上,模块是按变量 sys.path 指定的路径搜索的,此变量在解释程序启动时初始化为包含输入脚本的目录(或当前路径),PYTHONPATH 和安装缺省路径。这样,用户可以通过修改 sys.path 来修改和替换模块搜索路径。参见后面关于标准模块的一节。6.1.2 “编译”的 Python 文件为了提高调用许多标准模块的小程序的启动时间,一个重要的措施是,如果在找到“spam.py ”的目录中存在一个名为“spam.pyc”的文件,就认为此文件包含了模块 spam 的一个所谓“ 字节编译”版本。用于生成“spam.pyc”的