对于后一种情况,程序中类似于调用input()和raw_input()这样的输入请求,来自于确定的文件。
因为在解析器开始执行之前,文件已经完全读入,所以程序指向文件尾。
在前一种情况(这通常是你需要的)它们从来自于任何联接到Python解释器的标准输入,无论它们是文件还是其它设备。
使用脚本文件时,经常会运行脚本然后进入交互模式。
这也可以通过在脚本之前加上-i参数来实现。
(如果脚本来自标准输入,就不能这样运行,与前一段提到的原因一样。
)
2.1.1参数传递
调用解释器时,脚本名和附加参数之传入一个名为sys.argv的字符串列表。
没有脚本和参数时,它至少也有一个元素:
sys.argv[0]此时为空字符串。
脚本名指定为‘-’(表示标准输入)时,sys.argv[0]被设置为‘-’,使用-c指令时,sys.argv[0]被设定为‘-c’。
-c命令之后的参数不会被Python解释器的选项处理机制所截获,而是留在sys.argv中,供脚本命令操作。
2.1.2交互模式
从tty读取命令时,我们称解释器工作于交互模式。
这种模式下它根据主提示符来执行,主提示符通常标识为三个大于号(“>>>”);继续的部分被称为从属提示符,由三个点标识(“...”)。
在第一行之前,解释器打印欢迎信息、版本号和授权提示:
python
Python2.3(#1,Jul302003,23:
22:
59)
[GCC3.220020927(prerelease)]oncygwin
Type"help","copyright","credits"or"license"formoreinformation.
>>>
输入多行结构时需要从属提示符了,例如,下面这个if语句:
>>>the_world_is_flat=1
>>>ifthe_world_is_flat:
...print"Becarefulnottofalloff!
"
...
Becarefulnottofalloff!
2.2解释器及其环境
2.2.1错误处理
有错误发生时,解释器打印一个错误信息和栈跟踪(监视)器?
。
交互模式下,它返回主提示符,如果从文件输入执行,它在打印栈跟踪器后以非零状态退出。
(异常可以由try语句中的except子句来控制,这样就不会出现上文中的错误信息)有一些非常致命的错误会导致非零状态下退出,这由通常由内部矛盾和内存溢出造成。
所有的错误信息都写入标准错误流;命令中执行的普通输出写入标准输出。
在主提示符或附属提示符输入中断符(通常是Control-CorDEL)就会取消当前输入,回到主命令行。
[1]执行命令时输入一个中断符会抛出一个KeyboardInterrupt异常,它可以被try句截获。
2.2.2执行Python脚本
BSD系统中,Python脚本可以像Shell脚本那样直接执行,只要在脚本文件开头写一行命令,指定文件和模式:
#!
/usr/bin/envpython
(将用户路径通知解释器)“#!
”必须是文件的前两个字符,在某些平台上,第一行必须以Unix风格的行结束符(“\n”)结束,不能用Mac(“\r”)或Windows(“\r\n”)的结束符。
注意,“#”是Python中是行注释的起始符。
脚本可以通过chmod命令指定执行模式和许可权。
$chmod+xmyscript.py
2.2.3源程序编码
Python的源文件可以通过编码使用ASCII以外的字符集。
最好的做法是在#!
行后面用一个特殊的注释行来定义字符集。
#-*-coding:
iso-8859-1-*-
根据这个声明,Python会将文件中的字符尽可能的从指定的编码转为Unicode,在本例中,这个字符集是iso-8859-1。
在Python库参考手册中可以找到可用的编码列表(根据我的实验,中文似乎只能用cp-936或utf-8,不直接支持GB,GBK,GB-18030或ISO-10646--译者注)。
如果你的文件编辑器支持UTF-8格式,并且可以保存UTF-8标记(akaBOM-ByteOrderMark),你可以用这个来代替编码声明(看来至少Jext还不支持这样做,而Vim,我还没找到它的编码设置在哪里,还是老老实实的用注释行指定源代码的编码吧--译者注)。
IDLE可以通过设定Options/General/DefaultSourceEncoding/UTF-8来支持它。
需要注意的是旧版Python不支持这个标记(Python2.2或更早的版本),也同样不能使操作系统支持#!
文件。
使用UTF-8内码(无论是用标记还是编码声明),我们可以在字符串和注释中使用世界上的大部分语言。
标识符中不能使用非ASCII字符集。
为了正确显示所有的字符,你一定要在编辑器中将文件保存为UTF-8格式,而且要使用支持文件中所有字符的字体。
2.2.4交互式环境的启动文件
使用Python解释器的时候,我们可能需要在每次解释器启动时执行一些命令。
你可以在一个文件中包含你想要执行的命令,设定一个名为PYTHONSTARTUP的环境变量来指定这个文件。
这类似于Unixshell的.profile文件。
这个文件在交互会话期是只读的,当Python从脚本中解读文件或以终端作为外部命令源时则不会如此(尽管它们的行为很像是处在交互会话期。
)它与解释器执行的命令处在同一个命名空间,所以由它定义或引用的一切可以在解释器中不受限制的使用。
你也可以在这个文件中改变sys.ps1和sys.ps2指令。
如果你想要在当前目录中执行附加的启动文件,你可以在全局启动文件中加入类似以下的代码:
ifos.path.isfile('.pythonrc.py'):
execfile('.pythonrc.py')
如果你想要在某个脚本中使用启动文件,必须要在脚本中写入这样的语句:
importos
filename=os.environ.get('PYTHONSTARTUP')
iffilenameandos.path.isfile(filename):
execfile(filename)
3.Python的非正式介绍
在后面的例子中,区分输入和输出的方法是看是否有提示符(“>>>”和“..”):
想要重复这些例子的话,你就要在提示符显示后输入所有的一切;没有以提示符开始的行,是解释器输出的信息。
需要注意的是示例中的从属提示符用于多行命令的结束,它表示你需要输入一个空行。
本手册中的很多示例都包括注释,甚至有一些在交互提示符中折行。
Python中的注释以符号“#”起始,一直到当前行的结尾。
注释可能出现在一行的开始,也可能跟在空格或程序代码之后,但不会出现在字符串中,字符串中的#号只代表#号。
示例:
#thisisthefirstcomment
SPAM=1#andthisisthesecondcomment
#...andnowathird!
STRING="#Thisisnotacomment."
3.1初步认识Python
让我们试验一些简单的Python命令。
启动解释器然后等待主提示符“>>>”出现(这用不了太久)。
3.1.1数值
解释器的行为就像是一个计算器。
你可以向它输入一个表达式,它会返回结果。
表达式的语法简明易懂:
+,-,*,/和大多数语言中的用法一样(比如C或Pascal),括号用于分组。
例如:
>>>2+2
4
>>>#Thisisacomment
...2+2
4
>>>2+2#andacommentonthesamelineascode
4
>>>(50-5*6)/4
5
>>>#Integerdivisionreturnsthefloor:
...7/3
2
>>>7/-3
-3
像c一样,等号(“=”)用于给变量赋值。
被分配的值是只读的。
>>>width=20
>>>height=5*9
>>>width*height
900
同一个值可以同时赋给几个变量:
>>>x=y=z=0#Zerox,yandz
>>>x
0
>>>y
0
>>>z
0
Python完全支持浮点数,不同类型的操作数混在一起时,操作符会把整型转化为浮点数。
>>>3*3.75/1.5
7.5
>>>7.0/2
3.5
复数也同样得到了支持,虚部由一个后缀“j”或者“J”来表示。
带有非零实部的复数记为“(real+imagj)”,或者也可以通过“complex(real,imag)”函数创建。
>>>1j*1J
(-1+0j)
>>>1j*complex(0,1)
(-1+0j)
>>>3+1j*3
(3+3j)
>>>(3+1j)*3
(9+3j)
>>>(1+2j)/(1+1j)
(1.5+0.5j)
复数总是由实部和虚部两部分浮点数来表示。
可能从z.real和z.imag得到复数z的实部和虚部。
>>>a=1.5+0.5j
>>>a.real
1.5
>>>a.imag
0.5
用于向浮点数和整型转化的函数(float(),int()和long())不能对复数起作用--没有什么方法可以将复数转化为实数。
可以使用abs(z)取得它的模,也可以通过z.real得到它的实部。
>>>a=3.0+4.0j
>>>float(a)
Traceback(mostrecentcalllast):
File"",line1,in?
TypeError:
can'tconvertcomplextofloat;usee.g.abs(z)
>>>a.real
3.0
>>>a.imag
4.0
>>>abs(a)#sqrt(a.real**2+a.imag**2)
5.0
>>>
交互模式下,最近一次表达式输出保存在_变量中。
这意味着把Python当作桌面计算器使用时,它可以更容易的进行连续计算,例如:
>>>tax=12.5/100
>>>price=100.50
>>>price*tax
12.5625
>>>price+_
113.0625
>>>round(_,2)
113.06
>>>
这个变量对于用户来说是只读的。
不要试图去给它赋值--由于Python的语法效果,你只会创建一个同名的局部变量覆盖它。
3.1.2字符串
除了数值,Python还可以通过几种不同的方法操作字符串。
字符串用单引号或双引号标识:
>>>'spameggs'
'spameggs'
>>>'doesn\'t'
"doesn't"
>>>"doesn't"
"doesn't"
>>>'doesn"t'
'doesn"t'
>>>"doesn\'t"
"doesn't"
>>>"doesn\"t"
'doesn"t'
>>>"doesn\'t"
"doesn't"
>>>'doesn\"t'
'doesn"t'
>>>'"Yes,"hesaid.'
'"Yes,"hesaid.'
>>>"\"Yes,\"hesaid."
'"Yes,"hesaid.'
>>>'"Isn\'t,"shesaid.'
'"Isn\'t,"shesaid.'
字符串可以通过几种方式分行。
可以在行加反斜杠作为继续符,这表示下一行是当前行的逻辑沿续。
hello="Thisisaratherlongstringcontaining\n\
severallinesoftextjustasyouwoulddoinC.\n\
Notethatwhitespaceatthebeginningofthelineis\
significant."
printhello
注意换行用\n来表示;反斜杠后面的新行标识(newline,缩写“n”)会转换为换行符,示例会按如下格式打印:
Thisisaratherlongstringcontaining
severallinesoftextjustasyouwoulddoinC.
Notethatwhitespaceatthebeginningofthelineissignificant.
然而,如果我们创建一个“raw”行,\n序列就不会转为换行,示例源码最后的反斜杠和换行符n都会做为字符串中的数据处理。
如下所示:
hello=r"Thisisaratherlongstringcontaining\n\
severallinesoftextmuchasyouwoulddoinC."
printhello
会打印为:
Thisisaratherlongstringcontaining\n\
severallinesoftextmuchasyouwoulddoinC.
或者,字符串可以用一对三重引号”””或'''来标识。
三重引号中的字符串在行尾不需要换行标记,所有的格式都会包括在字符串中。
print"""
Usage:
thingy[OPTIONS]
-hDisplaythisusagemessage
-HhostnameHostnametoconnectto
"""
得到下面的输出:
Usage:
thingy[OPTIONS]
-hDisplaythisusagemessage
-HhostnameHostnametoconnectto
解释器打印出来的字符串与它们输入的形式完全相同:
内部的引号,用反斜杠标识的引号和各种怪字符,都精确的显示出来。
如果字符串中包含单引号,不包含双引号,可以用双引号引用它,反之可以用单引号。
(后面介绍的print语句,可以用来写没有引号和反斜杠的字符串)。
字符串可以用+号联接(或者说粘合),也可以用*号循环。
>>>word='Help'+'A'
>>>word
'HelpA'
>>>'<'+word*5+'>'
''
两个字符串值之间的联接是自动的,上例第一行可以写成“word='Help''A'”这种方式只对字符串值有