我们要用几个简单的范例程式,介绍 Python 的语法特色。由于这么作无法精确完整地描述 Python 的写法,所以推荐你继续 (依序) 阅读 PingYeh 的 Python 教材 [7] (中文)、Python Online Tutorial [8],以及比较硬的 Python Language Reference [9];另外,Dive into Python [10] 也是一本可以在网路上免费下载的好书,值得参考。
让我们来写 Python 程式吧!Python 程式通常会存成 .py 档,在 Windows 下的 Python 安装程式会自动把这种副档名和 Python 直译器程式关联起来,所以在指令行介面 (cmd.exe) 下输入 “blahblah.py” 这样的字眼,就会执行这个程式。而在 Linux 或其它 Unix-like 的系统里面,就要再打开该档案的执行权限 (通常以 chmod a+x blahblah.py 进行)。不管你使用哪种系统,我们还是先来 hello.py 一下:
#!/usr/bin/env python print "Hello, world"
执行的结果是 (Linux 环境):
$ ./hello.py
Hello, world
要让 Python 程式在 Windows 下执行的关键是副档名 .py,而要在 Linux 下执行的关键除了执行权限要设定之外,还有一个就是 hello.py 第一行的“标头”。在 Linux 下所有像 Python 这类的指令稿,在档案的最前头都必须要指定所使用的直译器;在这里写为 ”#!/usr/bin/env python”,表示使用系统路径里第一个找到的 python 直译器 (你的系统里可能装了不止一个 Python 喔),也就是预设的直译器。如果没有这个“标头”,Linux 就不知道它是个 Python 程式了。
再来一个读取档案的例子 fileproc.py:
#!/usr/bin/env python f = open( "/var/log/messages" ) lines = f.readlines() f.close() for line in lines: print line
从第 2 行开始,程式会先打开 /var/log/messages 这个档案 (Linux 的标准纪录档之一),然后用档案物件 (open 函式会传回档案物件,我们取名为 f) 的 readlines() 方法一次读取所有的文字行,然后在第 4 行关闭档案。接着是重要的回圈叙述;lines 是用来存放所有文字行的列表,for line in lines 这个叙述的意思是“一次取 lines 列表中的一个项目,取名为 line”。在 for 回圈叙述后加上冒号,换行然后“缩排”,同一段缩排的程式表示是一个区块;我们这个 for 回圈的区块里只包含了一行叙述,就是把 line 印到萤幕上。
/var/log/messages 档里的资料应该很多,你会看到一大堆字串跑过萤幕。这就表示程式执行成功了。在 Windows 下,请更换一下 open() 函式所打开的档案,只要是纯文字档即可。
Python 里的字串可以用单引号 (') 或用双引号 (”) 包围的文字来表示,效果一样。我们接下来要说明 Python 字串处理能力,顺便展示 Python 的互动式环境。在 Windows 下打开指令行介面 (cmd.exe),输入 C:\Python23\python;在 Linux 下的终端机内直接输入 python,都可以进入互动式环境:
$ python Python 2.3.5 (#2, Aug 30 2005, 15:50:26) [GCC 4.0.2 20050821 (prerelease) (Debian 4.0.1-6)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>
在 Linux 下要跳出时是按 Ctrl-D,而在 Windows 下则是按 Ctrl-Z。通常 Python 互动式环境的提示符号是如上的 »>。再来,试着输入以下指令:
>>> print "a b c".split() ['a', 'b', 'c']
字串在 Python 里也是一种物件,所以我们可以如上呼叫字串方法 split()。在不加参数的情况下,split() 方法会用字串里的广义空白 (包含空白、跳格与断行等字元;连续的广义空白字元视为单一的广义空白) 来把字串断成多个字串,并传回包含这些字串的列表。我们可以指定列表元素的索引值来单独存取这些字串:
>>> print 'this is an apple'.split()[2] an
这样就取出了编号 2 的第三个单字 “an”。我们可以把这个技巧应用在之前读取档案的程式里;只要知道档案的格式,就能筛选出我们想要的字串资料。
如果我们想把字串写进档案,首先要用写入模式来开启新档:
f = open( "newfilename.txt", 'w' )
再用档案物件的 write() 方法来写入字串:
f.write( "string data" )
最后不要忘了用 f.close() 关闭档案。
Python 模组 (module) 是一种非常方便的设计;适当地利用模组可以在不污染命名空间的情况下获得额外功能。模组的汇入是利用 import 叙述:
import sys
它汇入了最常用的 sys 内建模组。如果我们想处理指令行引数,就要靠 sys 模组里的变数 argv:
#!/usr/bin/env python import sys print sys.argv
把这个程式存为 echoargs.py,然后执行:
$ ./echoargs.py arg1 arg2 ['./echoargs.py', 'arg1', 'arg2']
它把所有的指令行引数都印了出来,以列表的形式。sys.argv 这个变数实际上是个列表,它与 C 程式 main() 进入点函式的 argv 参数有异曲同工之妙,连名字都取作一样;只是更为好用,因为 Python 的列表比 C 阵列自动化得太多,我们不必担心列表项目的个数问题,Python 会帮我们处理好的。
Python 还有许多其它的模组,基本上都是以相同的方式汇入并使用的,请参阅线上手册。
Python 程式语言的一个最大的特色就是以缩排定义程式结构。不像 C, C++, Java 等语言用括号定义程式区块 (类别、函式、条件判断和回圈等),在 Python 里,行首的“空白字元个数” (即缩排) 就定义了区块结构。许多会写像
int main(){ int i; double d; d = 1.d0; i = 2; }
这种程式的人一开始会非常不习惯这种作法;但所有程式设计的书都会告诉你程式码应该要排整齐,乱排只会增加往后维护的困难度而已。Python 强迫程式员把程式写得漂亮,这不单简化了往后的维护工作,更去掉了程式里那些扰人的括号,对减少程式码长度来说效果良好。
在 Python 里,
print "Hi" print "hi"
是不合法的,要写成
print "Hi" print "hi"
才可以。相对地,
if 1 == 1: print "1 == 1, of course"
是错误的写法,要写成像
if 1 == 1: print "1 == 1, of course"
这样才对。
至于一次缩排要缩多少个字元,Python 并没有进行限制,甚至不同的段落空白不一样长也可以;只要同一个区块的行首空白数相同即可。然而经验告诉我们,第一,“绝对不要用跳格键”,如果你用 VIM 写程式,可以用 :set et 打开跳格键的空白取代功能 (好一点的编辑器一定都有这种功能,你的编辑器没有的话,可能该考虑换一个了);第二,缩排字元数要固定。Python 的爸爸 Guido van Rossum 喜欢用 4 个字元进行缩排,许多人都觉得这样很好。