对后者而言,不单单只有执行这个script,而且程序中有关输入的需求(例如呼叫input()或是raw_input())也都会由这个file来满足。
由于此file已经在程序执行之初已经被从头到尾读过一次,所以一执行这个程序将会马上就碰到了EOF。
相反的对于前一个写法来说,程序的输入需求是由任何连结到Python直译器的标准输入(standardinput)的装置或档案来满足的,而这个也许才是你所想要的结果。
当script档案在使用的时候,也许你会想要执行这个script然后还可以之后继续进入互动的模式。
这时你可以加入-i这个选项。
但是如同前一段所说的,如果此script是由标准输入来读进去的话就没有办法这样做了。
3.1.1参数的传递
如果interpreter认识sys的话(译:
可用“importsys”指令),script的文件名及附加传入的参数都会被纪录在sys.argv这个变量并并传给script来使用。
sys.argv是一列的字符串,长度至少为1,如果你什么都档案或参数都没传的话,sys.argv[0]就是一个空字符串。
如果script的名字是'-'(就是标准输入的意思)的话,sys.argv[0]就会被设为'-'。
当使用-ccommand的话,sys.argv[0]就被设定为'-c'所有的在-ccommand之后的option(例如–i)都会被当成sys.argv而被command所处理,所以就不是当作option一样的来看待了。
3.1.2互动模式
当指令是由tty终端机来传入时,我们称之为互动模式(interactivemode)。
在此模式之下会出现主要的命令提示符号(primaryprompt)来提示输入下一个指令,这个primaryprompt通常是">>>"。
如果是指令是延续上一行的话就会出现secondaryprompt符号,这个secondaryprompt就通常是"..."。
一进入python的互动模式的话直译器会出现一个欢迎信息,以及版本编号辑版权说明,接下来就是第一个prompt。
如下所示:
python
Python1.5.2b2(#1,Feb281999,00:
02:
06)[GCC2.8.1]onsunos5
Copyright1991-1995StichtingMathematischCentrum,Amsterdam
>>>
当你输入需要多行的结构时,直译器就会自动会出现延续上一行的prompt符号,下面的例子是if叙述的情况:
>>>the_world_is_flat=1
>>>ifthe_world_is_flat:
...print"Becarefulnottofalloff!
"
...
Becarefulnottofalloff!
3.2直译器及其周边环境
3.2.1程序错误处理
当有错误产生时,直译器就会在屏幕印出错误的信息以及stacktrace的所有数据。
在互动模式之下,印完数据之后会再印出prompt来。
如果输入是来自于档案的话,在出现错误的情况下直译器在印出stacktrace之后程序会以nonzeroexit的状态结束。
(此处讨论不包含已经由try叙述及except子句处理外的状况(Exceptions))。
有些的程序错误是没有办法挽救并且会造成nonzeroexit的结束情况,这常常是内部的不一致或是某种runningoutofmemory所造成。
所有的错误信息都会被写入至标准errorstream之中,正常的程序执行的输出则会写入到标准(standardoutput)输出之中。
如果在primary或是secondaryprompte之下打入中断字符(通常是Control-C或是DEL),这会造成输入的中断并且会回到prompt之下。
(有一个GNUReadlinepackage的问题可能会使这个功能失效。
)在指令执行之中打入中断字符则会引起KeyboardInterrupt的exception,而这是可以在try叙述中处理的。
3.2.2执行Python脚本
在BSD之类的Unix系统上,我们可以在script的最前面加入以下的叙述(类似shellscript),并改变档案属性为可执行:
#!
/usr/bin/envpython
如此script就会变成可执行档,可以直接执行(假设Python的直译器是在user的$PATH)变量之中)。
"#!
"这两个字必须在script档案的最前面。
值得一提的是"#"在Python之中也当作注解(comment)部分开始的符号。
3.2.3交互式启动档
当你使用互动模式的时候,如果可以在每次直译器要启动时先执行一些命令的话将是很有用的。
要达成如此功能,你可以设定一个文件名称给环境变量$PYTHONSTARTUP,这个档案可以包含你想要在启动时执行的命令,类似.profile在Unixshell中的用法。
这个启动档(startupfile)只有对在互动模式下有效,如果你用Python读入script时就没有用,在当/dev/tty是命令的输入来源也没有用(其它的情况与互动模式相类似)。
这个startupfile所执行命令的命名空间是与其它互动模式下输入的指令相同,所以在startupfile内定义或是import的对象,在之后的互动模式指令中都是可以直接使用的。
你也可以在这个startupfile中改变sys.ps1及sys.ps2,如此就可以改变你的primaryprompt及secondaryprompt。
如果你在你的startupfile中想要使用另外的在目前目录的startupfile,你只需要在主要startupfile(globalstart-upfile)写入"ifos.path.isfile('.pythonrc.py'):
execfile('.pythonrc.py')"。
如果你想要在你的script之中使用startupfile的话,你必须在你的script中写入:
importos
filename=os.environ.get('PYTHONSTARTUP')
iffilenameandos.path.isfile(filename):
execfile(filename)
4非正式的Python介绍
在底下的例子里,你可以很容易区别凡是需要输入的地方都会出现prompts(">>>"或"..."),凡是输出的结果则没有。
如果你想要跟着这个教学文件一起做的话,你就得打入所有在prompts之后的指令,凡是没有prompts出现的行就是直译器输出的结果。
值得注意的是,secondarypromt之后如果什么东西都没有,表示这是一个空行(直接按ENTER的结果),也表示这是一个多行指令的结束。
在本文件中的大部分例子,都有加上注释,甚至是那些互动模式下的例子。
注释(comment)在Python中是以"#"之后的东西都是注释(译:
跟Perl一样)。
注释可以自成一行,也可以跟在空格符或是程序代码的后面。
但是,如果"#"是在字符串常数(stringliteral)之中的话,就不代表注释的意义,而只是一个普通字符罢了。
底下是一些例子:
#thisisthefirstcomment
SPAM=1#andthisisthesecondcomment
#...andnowathird!
STRING="#Thisisnotacomment."
4.1把Python当作计算器来用
现在我们来试一试一些简单的Python指令吧。
请先启动Python的直译器并且等待primaryprompt(">>>")的出现。
(应该不会很久的)
4.1.1数字
直译器就好像一个计算器一样:
你可以打入一个表示式(expression),然后直译器会把这个expression的执行结果秀出来。
Expression的语法都很简单直接,一般的运算符号+,-,*以及/的用法就跟其它的程序语言(像是Pascal或C)一样。
你也可以用括号"()"来表示运算执行的先后次序。
例子如下:
>>>2+2
4
>>>#Thisisacomment
...2+24
>>>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里面也是支持的,如果整数与浮点数(带小数点或e的数)进行运算的话,整数部分会先转换(convert)成浮点数再进行运算。
>>>4*2.5/3.3
3.0303030303
>>>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)
复数的虚数部分及实数部分的值都是以浮点数(floatpointnumbers)来表示的,如果z代表一个复数的话,你可以很轻易的用z.real以及z.imag得到一个复数的实数部分及虚数部分。
>>>a=1.5+0.5j
>>>a.real
1.5
>>>a.imag
0.5
复数没有办法直接用(float(),int()或是long())转换成浮点数或是整数。
事实上,复数没有直接对应的实数,你必须用abs(z)来得到z的magnitude(以浮点数表示),或是如上所述用z.real直接得到其实数部分。
>>>a=1.5+0.5j
>>>float(a)
Traceback(innermostlast):
File"",line1,in?
TypeError:
can'tconvertcomplextofloat;usee.g.abs(z)
>>>a.real
1.5
>>>abs(a)
1.58113883008
在互动模式之下,最后一个印出来的expression的值会储存在一个特殊变量"_"之中。
这表示,当你用Python的直译器来当作计算器用的时候,想要连续做运算其实是方便许多的。
如下例:
>>>tax=17.5/100
>>>price=3.50
>>>price*tax
0.61249999999999993
>>>price+_
4.1124999999999998
>>>round(_,2)
4.1100000000000003
对于使用者来说,"_"这个变数是一个只读的变数。
你没有办法设定一个值给它,当你这样做的时候,事实上你是重新创造一个同名的变量,但是跟之前系统内建的"_"这个变量是一点关系也没有的了。
4.1.2字符串
除了数字之外,Python也有能力处理字符串(string)。
字符串在Python中有很多种表达方式,它可以放在双括号””之中,也可以放在单括号’’里面:
>>>'spameggs'
'spameggs'
>>>'doesn\'t'
"doesn't"
>>>"doesn't"
"doesn't"
>>>'"Yes,"hesaid.''
"Yes,"hesaid.'
>>>"\"Yes,\"hesaid."
'"Yes,"hesaid.'
>>>'"Isn\'t,"shesaid.'
'"Isn\'t,"shesaid.'
字符串常数(stringliterals)是可以跨越多行的,其表示方法有很多。
如果要换行的话可以用”
}”符号来表示之。
如下例:
hello="Thisisaratherlongstringcontaining\n\
severallinesoftextjustasyouwoulddoinC.\n\
Notethatwhitespaceatthebeginningofthelineis\
significant.\n"
printhello
这个例子会印出以下的结果:
Thisisaratherlongstringcontaining
severallinesoftextjustasyouwoulddoinC.
Notethatwhitespaceatthebeginningofthelineissignificant.
你也可以用成对的三个单引号(""")或双引号(''')来表示字符串。
在此情况下你所打入的ENTER就会直接被解读为换行符号而不需要再用\n了。
print"""
Usage:
thingy[OPTIONS]
-hDisplaythisusagemessage
-HhostnameHostnametoconnectto
"""
这个例子