Differences between revisions 9 and 11 (spanning 2 versions)
Revision 9 as of 2006-01-17 13:38:36
Size: 16905
Editor: WeiZhong
Comment:
Revision 11 as of 2006-01-17 17:58:16
Size: 9497
Editor: WeiZhong
Comment:
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
Python Essential Reference, Second Edition 译文 Python Essential Reference Second Edition 译文
Line 7: Line 7:
初译: Feather andelf@gmail.com
修正补充: WeiZhong weizhong2004@gmail.com
初译: Feather andelf@gmailcom
修正补充: WeiZhong weizhong2004@gmailcom
Line 11: Line 11:
= 第一章 Python快速入门 =
本章是Python的快速入门,在这一章并不涉及python的特殊规则和细节,目标是通过示例使你快速了解Python语言的特点。本章简要介绍了变量,表达式,控制流,函数以及输入/输出的基本概念,在这一章不涉及Python语言的高级特性。尽管如此,有经验的程序员还是能够通过阅读本章的材料创建高级程序。我们鼓励新手通过运行示例,亲身体验一把Python。
= 第二章 语法及代码约定 =
Line 14: Line 13:
== 运行Python ==
Python 程序通过解释器执行。如果你的机器已经装好了python,简单的在命令行键入python即可运行python解释器。在解释器运行的时,会有一个命令提示符 >>>,在提示符后键入你的程序语句,键入的语句将会立即执行。在下边的例子中,我们在>>>提示符后边键入最常见的显示"Hello World"的命令:
本章讲述了Python程序的语法和代码约定。
本章的主题有行结构,语句分组,保留字,字符串,运算符,token等等,另外对如何使用 Unicode 字符串也做了详细的描述。

== 行结构/缩进 ==

程序中的每个语句都以换行符结束。特别长的语句可以使用续行符(\)来分成几个短小的行,如下例:
Line 17: Line 20:
Python 2.4.2 (#67, Sep 28 2005, 12:41:11) [MSC v.1310 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> print "Hello World"
Hello World
>>>
import math
a = math,cos(3*(x-n)) + \
    math,sin(3*(y-n))
}}}
当你定义一个三引号字符串、列表、tuple 或者字典的时候不需要续行符来分割语句。及就是说,在程序中,凡是圆括号(,,,)、方括号[,,,]、花括号{,,,}及三引号字符串内的部分均不需要使用续行符。
Line 23: Line 26:
缩进被用来指示不同的代码块,比如函数的主体代码块,条件执行代码块,循环体代码块及类定义代码块。缩进的空格(制表符)数目可以是任意的,但是在整个块中的缩进必须一致:
{{{#!python
if a:
   statement1 # 缩进一致,正确!
   statement2
else:
   statement3
     statement4 #缩进不一致,错误!
}}}{{{
如果块中只有很少的语句,那么你也可以把它们放置在同一行:
Line 24: Line 37:
程序也可以像下面一样放置在一个文件中 if a: statement1
else: statement2
Line 26: Line 40:
# helloworld.py
print "Hello World"
要表示一个空的块或是空的主体,使用 pass语句:
Line 29: Line 42:
Python源代码文件使用.py后缀.'#'表示注释(到行末结束) if a:
   pass
else:
   statements
}}}
尽管允许用制表符指示缩进,我还是要说这是一个不好的习惯。
坚决不要混合使用制表符和空格来缩进,这会给你带来意想不到的麻烦。建议你在每个缩进层次中使用单个制表符或两个或四个空格。运行 Python的时候使用 -t 参数,如果python 发现存在制表符和空格混用,它就显示警告信息,若使用 -tt 参数 python 则会在遇到混用情况时引发TabError异常。
Line 31: Line 50:
执行文件helloworld.py 分号(;)可以把多个语句放在同一行中,只有一个语句的行也可以用分号来结束。
Line 33: Line 52:
% python helloworld.py
Hello World
%
#指示这是一个延长至行末的注释,但是包在字符串内的#没有这个功能。

最后要说明的,解释器会忽略所有的空白行(非交互模式下)。

== 标识符及保留字 ==

标识符是用于识别变量、函数、类、模块以及其他对象的名字,标识符可以包含字母、数字及下划线(_),但是必须以一个非数字字符开始。字母仅仅包括ISO-Latin字符集中的A–Z和a–z。标识符是大小写敏感的,因此 FOO和foo是两个不同的对象。特殊符号,如$、%、@等,不能用在标识符中。另外,如 if,else,for 等单词是保留字,也不能将其用作标识符。下面的表列出了所有的保留字符:
{{{
and elif global or
assert else if pass
break except import print
class exec in raise
continue finally is return
def for lambda try
del from not while
Line 37: Line 68:
在Windows 下,可能通过双击一个.py文件来执行python程序。windows会自动调用python解释程序,然后启动一个终端窗口(类DOS窗口)执行程序。在这种情况下,终端窗口会在程序执行完毕后立即关闭(经常是在你看到它的输出之前)。为避免这个问题,你可以使用python集成开发环境,例如IDLE或Pythonwin。另一个可行的方法是建立一个 bat文件,在文件写入这样一行语句,如 python -i helloworld.py。运行这个批处理,程序在执行完成后会自动进入python解释器。 以下划线开始或者结束的标识符通常有特殊的意义。例如以一个下划线开始的标识符(如 _foo)不能用from module import *语句导入。前后均有两个下划线的标识符,如__init__,被特殊方法保留。前边有两个下划线的标识符,如__bar,被用来实现类私有属性,这个将在第七章--类与面向对象编程中讲到。通常情况下,应该避免使用相似的标识符。
Line 39: Line 70:
在解释器中,也可以通过函数execfile()来运行一个保存在磁盘上的程序,如下例: == 数字/文字 ==

Python中有四种内建的数值类型:整数、长整数、浮点数和复数。

象1234这样的数被解析为一个十进制的整数。要指定一个八进制或者十六进制的整数,在一个合法的八进制数前加上 0 或者在一个合法的16进制数前加上 0x 就可以了。(如 0644 和 0x100fea8)。 在一个整数后面加上字母 l 或 L系统就认为这是一个长整数(如 1234567890L)。与受机器字长限制整数类型不同,长整数可以是任何长度(只受内存大小限制)。象123.34和1.2334e+02这样的数被解析为浮点数。一个整数或者浮点数加上后缀 J 或者 j 就构成了一个复数的虚部,你可以用一个实数加上一个虚部创建一个复数,比如 1.2 + 12.34J。

Python目前支持两种类型的字符串:

8位字符数据 (ASCII)

16位宽字符数据 (Unicode)

最常用的是ASCII字符串,因为这个字符集刚好只用一个字节就可以字符集中的任意一个字符。通常情况下,ASCII串用单引号('),双引号("),或者三引号(''' 或 """)来定义。字符串前后的引号类型必须一致。反斜杠(\)用来转义特殊字符,比如换行符、反斜杠本身、引号以及其他非打印字符。Table 2.1中列出了公认的特殊字符的表示方法,无法识别的转义字符串将被原样保留(包括前边的反斜杠)。此外,字符串可以包含嵌入的空字节和二进制数据。三引号字符串中可以包含不必转义的换行符和引号。

Table 2.1 Standard Character Escape Codes

标准特殊字符

||字符 || 描述||

|| \ ||续行符||

||\\ || 反斜杠||

||\'||单引号||

||\"||双引号||

||\a||Bell(音箱发出吡的一声)||

||\b||退格符||

||\e||Escape||

||\0||Null(空值)||

||\n||换行符,等价于\x0a和\cJ||

||\v||垂直制表符,等价于\x0b和\cK||

||\t||水平制表符,等价于\x09和\cI||

||\r||回车符,等价于\x0d和\cM||

||\f||换页符,等价于\x0c和\cL||

||\OOO||八进制值(000-377)||

||\xhh||十六进制值(x00-xff)||

||\un||Unicode字符值,n是四个十六进制数字表示的Unicode字符||
Line 41: Line 122:
>>> execfile("helloworld.py")
Hello World
Unicode 字符串用来表示多字节国际字符集,它包括65,536个字符。Unicode字符使用u或者U前缀来定义,例如`a = u"hello"`。在Unicode字符集中,每一个字符用一个16位整数来表示。Unicode字符使用 U+XXXX 这种形式来表示,XXXX是一个由 4 个十六进制数字组成的16进制数。(注意: 这种记法只是一个表示Unicode字符的习惯,并不是Python的语法)。例如U+0068是Unicode字符字母h(在Latin-1字符集中,你可以发现Unicode字符集的前256个字符与Lation-1的对应字符编码完全相同)。当Unicode字符串被赋值时普通字符和特殊字符都直接转换成Unicode字符序数(在[U+0000, U+00FF]中)。例如,字符串"hello\n"映射为ASCII时是:0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a,当使用u"hello\n"转换为Unicode字符串时是:U+0068, U+0065, U+006C, U+006C, U+006F, U+000A.任意Unicode字符都可以使用\uXXXX来定义,\uXXXX必须位于一个Unicode字符串中,例如:
Line 44: Line 124:
在UNIX下,你可以在程序的首行写入 #! 魔法字符串 来自动调用python解释器执行你的脚本。 s = u"\u0068\u0065\u006c\u006c\u006f\u000a"
Line 46: Line 126:
#!/usr/local/bin/python
print "Hello World"
在Python 的较老版本中,\xXXXX字节序列被用来定义Unicode字符(这与系统识别Unicode字符方式有关)。虽然现在仍然允许这样做,我仍然建议你最好采用新的表示方法。(因为旧的表示方法随时可能废止。)另外,八进制代码\OOO也可以用来定义在[U+0000, U+01FF]中的Unicode字符。
Line 49: Line 128:
解释器会一直运行直到文件结束。如果在交互模式下,键入 EOF字符退出解释器。在UNIX下,EOF字符是Ctrl+ D;在Windows下,EOF字符是Ctrl+Z.也可以在程序中使用sys.exit()函数或者通过引发SystemExit异常来退出程序: Unicode字符不能通过使用 UTF-8或者UTF-16编码中的原始字节序列来定义。例如,UTF-8编码的字符串 u'M\303\274ller' 建立的七个字符,用Unicode表示为+004D, U+00C3, U+00BC, U+006C, U+006C, U+0065, U+0072,这并不是你想要的结果。这是因为在UTF-8中,多字节序列\303\274用来代表U+00FC,而不是U+00C3, U+00BC。更多关于Unicode编码细节你可以阅读第三章--"类型和对象",第四章--"运算符和表达式",第九章--"输入和输出".
Line 51: Line 130:
>>> import sys
>>> sys.exit()
你可以给一个字符串加上前缀r或者R,例如 `r'\n\"'`,这些字符串被称为原始字符串,因为里边几乎所有的特殊字符都会原封不动地留下。不过原始字符串并不能以一个单独的反斜杠结尾(例如 r"\")。如果原始字符串使用ur或者UR前缀来定义的话,\uXXXX仍然会被解析为Unicode字符。如果你不想这样,你可以在它前边再加一个反斜杠,例如ur"\\u1234",它定义了一个含有7个字符的字符串。需要注意的是,定义原始Unicode字符串时,r必须在u之后。
Line 54: Line 132:
或者 邻近的字符串(被空格或者续行符分割),例如 "hello" 'world' 会被Python自动连结为一个字符串 "helloworld"。无论是普通字符串,Unicode字符串,还是自然字符串,都会自动连结。当然,只要这些字符串中有一个是Unicode字符串,那最终连结的结果也将是一个Unicode字符串。比如 "s1" u"s2" 就会产生 u"s1s2"。这个过程的细节你可以阅读第四章和附录A(the Python library).
Line 56: Line 134:
>>> raise SystemExit 如果Python在 -U 命令行参数下运行,所有的字符都会被解析为Unicode。

方括号[...]定义一个列表,圆括号(...)定义一个元组,花括号{...}定义一个字典:

 a = [ 1, 3.4, 'hello' ] # A list
 b = ( 10, 20, 30 ) # A tuple
 c = { 'a': 3, 'b':42 } # A dictionary
Line 58: Line 142:

== 变量和表达式 ==

通过Listing 1.1所示的程序示例变量和表达式的用法

Listing 1.1 复利计算器(Simple Compound-Interest Calculation)
{{{#!python
principal = 1000 # Initial amount (本金)
rate = 0.05 # Interest rate (利率)
numyears = 5 # Number of years (期数,年)
year = 1
while year <= numyears:
        principal = principal*(1+rate)
        print year, principal
        year += 1
}}}
程序输出:
{{{
1 1050.0
2 1102.5
3 1157.625
4 1215.50625
5 1276.2815625
}}}
Python 是一种动态语言,在程序运行过程中,同一变量名可以(在程序运行的不同阶段)代表不同形式的值(整型,浮点,列表,元组...)。事实上,程序中使用的变量名只是各种数据及对象的引用。这与C语言不同,C语言中变量名代表的是用来存放结果的一个固定位置及长度的内存片段。从例子Listing 1.1中的变量principal可以看出Python语言的动态特性.最初,它被赋值为一个整数,但是稍后程序将它再次赋值:

`principal = principal*(1+rate)`

这个语句计算表达式的值,然后将计算结果赋给 principal 变量做为它的新值。当赋值动作发生时,principal最初绑定的值1000被丢弃。赋值结束,不但 principal 绑定的值发生了变化,它的类型也随着赋值动作发生了相应的变化。在这个例子中,由于rate是一个浮点数,所以在赋值完成后,principal也变成一个浮点数。

Python中每个语句以换行结束,当然你也可以在一行中写多个语句,这时语句之间必须使用用分号分隔,就象下面这样:

`principal = 1000; rate = 0.05; numyears = 5;`

(建议这样的写法仅仅用于调试语句,因为可以很方便的只删一行就删掉全部调试语句)

while 语句首先检查在它后边的循环条件,若条件表达式为真,它就执行冒号后面的语句块,然后再次测试循环条件,直至为假。冒号后面的缩近语句块为循环体。注意,Python语言使用缩进块来表示程序逻辑(其它大多数语言使用大括号等)。在Listing 1.1中while语句后的三条语句为循环体,在每次循环中均执行。Python并未指定缩进的空白(空格和制表符)数目,唯一的要求是同一层次的语句必须有相同的缩进空白。(注意,要么都是空格,要是么都制表符,千万别混用)

Listing 1.1中的程序美中不足的就是输出不是很好看,为了让它美观一点,可以用格式字符串将计算结果只保留小数点后两位:
{{{
print "%3d %0.2f" % (year, principal)

这样,程序的输出就变为:

1 1050.00
2 1102.50
3 1157.63
4 1215.51
5 1276.28
}}}
格式字符串包含普通文本及格式化字符序列(例如"%d", "%s", 和 "%f"),这些序列决定特定类型的数据(如整型,字符串,浮点数)的输出格式.'%3d'将一个整数在宽度为3个字符的栏中右对齐,'%0.2f'将一个浮点数的小数点后部分转换为2位。格式字符串的作用和C语言中的sprintf()函数基本相同。详细内容请参阅第四章--操作符及表达式。
== 条件语句 ==

if和else语句用来进行简单的测试,如:
{{{#!python
# Compute the maximum (z) of a and b (得到a与b中较大的一个)
if a < b:
        z = b
else:
        z = a
}}}
if和else的语句块用缩近来表示,else从句在某些情况下可以省略。
如果if或else语句块只有一个语句,也可以不使用缩近。也就是说:
{{{#!python
if a<b: z=a
else: z=b
}}}
这样的写法也是合法的,但这不是推荐的作法。一直使用缩近可以让你方便的在语句体中添加一个语句,而且读起来更清晰。
若某个子句不需任何操作,就使用pass语句,如:
{{{#!python
if a < b:
        pass # Do nothing
else:
        z = a
}}}
通过使用 or,and 和 not 关键字你可以建立任意的条件表达式:
{{{#!python
if b >= a and b <= c:
        print "b is between a and c"
if not (b < a or b > c):
        print "b is still between a and c"
}}}
用 elif 语句可以检验多重条件(用于代替其它语言中的switch语句):
{{{#!python
if a == '+':
        op = PLUS
elif a == '-':
        op = MINUS
elif a == '*':
        op = MULTIPLY
else:
        raise RuntimeError, "Unknown operator"
}}}

== 文件输入/输出 ==

下面的程序打开一个文件,然后一行行地读出并显示文件内容:
{{{#!python
f = open("foo.txt") # Returns a file object
line = f.readline() # Invokes readline() method on file
while line:
        print line, # trailing ',' omits newline character
        line = f.readline()
f.close()
}}}
`open()`函数返回一个新文件对象(file object)。通过调用此对象的不同方法可以对文件进行不同的操作。`readline()`方法读取文件的一行(包括换行符'\n')。如果读到文件末尾,就返回一个空字符串。要将程序的输出内容由屏幕重定向到文件中,可以使用'>>'运算符,如下例:
{{{#!python
f = open("out","w") # Open file for writing
while year <= numyears:
        principal = principal*(1+rate)
        print >>f,"%3d %0.2f" %% (year,principal) #将格式文本输出到文件对象 f
        year += 1
f.close()
}}}
当然,文件对象也拥有`write()`方法,通过它可以向文件对象写入新的数据。例如上边例子中的print的语句也可以写成这样:

`f.write("%3d %0.2f\n" % (year,principal)) `

== 字符串 ==

要创建一个字符串,你使用单引号,双引号或三引号将其引起来,如下例:
{{{#!python
a = 'Hello World'
b = "Python is groovy"
c = """What is footnote 5?"""
}}}
一个字符串用什么引号开头,就必须用什么引号结尾。两上三引号之间的一切都作为字符串的内容,对应的单引号与双引号却只能创建单行字符串。如下例:
{{{#!python
print '''Content-type: text/html

<h1> Hello World </h1>
Click <a href="http://www.python.org">here</a>.
'''
}}}
字符串是一个以0开始,整数索引的字符序列,要获得字符串 s 中的第 i+1 个字符(别忘了0是第一个),使用索引操作符 s[i]:
{{{#!python
a = "Hello World"
b = a[4] # b = 'o'
}}}
要获得一个子串,使用切片运算符 s[i:j]。 它返回字符串 s 中从索引 i (包括i)到 j (不包括 j)之间的子串。若 i 被省略,python就认为 i=0,若 j 被省略,python就认为 j=len(s)-1:
{{{#!python
c = a[0:5] # c = "Hello"
d = a[6:] # d = "World"
e = a[3:8] # e = "lo Wo"
}}}
可以用加(+)运算符来连结字符串:

`g = a + " This is a test"`

通过使用str()函数,repr()函数或向后的引号(`)可以将其他类型的数据转换为字符串:
{{{#!python
s = "The value of x is " + str(x)
s = "The value of y is " + repr(y)
s = "The value of y is " + `y`
}}}
repr()函数用来取得对象的规范字符串表示,向后的引号(`)是repr()函数的快捷版。

在大多情况下str()和repr()函数会返回同一个结果,但是它们之间有很微妙的差别,后边的章节对此将有详细描述。

== 列表和元组(Lists & Tuples) ==

就如同字符串是字符的序列,列表和元组则是任意对象的序列。象下面这样就可以创建一个列表:

`names = [ "Dave", "Mark", "Ann", "Phil" ]`

列表和元组都是以整数0来开始索引的序列,你可以用索引操作符来读取或者修改列表中特定元素的值:
{{{
a = names[2] # Returns the third item of the list, "Ann"
names[0] = "Jeff" # Changes the first item to "Jeff"

用len()函数得到列表的长度:

print len(names) # prints 4

append()方法可以把一个新元素插入列表的末尾:

names.append("Kate")

aList.insert(index,aMember)方法可以把新元素 aMember 插入到列表 aList[index] 元素之前:

names.insert(2, "Sydney")

用切片操作符可以取出一个子列表或者对子列表重新赋值:

b = names[0:2] # Returns [ "Jeff", "Mark" ]
c = names[2:] # Returns [ "Sydney", "Ann", "Phil", "Kate" ]
names[1] = 'Jeff' # Replace the 2nd item in names with "Jeff"
names[0:2] = ['Dave','Mark','Jeff'] # 用右边的 list 替换 names 列表中的前两个元素
    
加(+)运算符可以连结列表:

a = [1,2,3] + [4,5] # Result is [1,2,3,4,5]

列表元素可以是任意的 Python 对象,当然也包括列表:

a = [1,"Dave",3.14, ["Mark", 7, 9, [100,101]], 10]

子列表的元素用下面的方式调用:

a[1] # Returns "Dave"
a[3][2] # Returns 9
a[3][3][1] # Returns 101
}}}
Listing 1.2中代码从一个文件中读取一系列数字,然后输出其中的最大值和最小值。
通过这个示例我们可以了解到列表的一些高级特性:

Listing 1.2 列表的高级特性
{{{#!python
import sys # Load the sys module (导入sys模块)
f = open(sys.argv[1]) # Filename on the command line (从命令行读取文件名)
svalues = f.readlines() # Read all lines into a list (读出所有行到一个列表)
f.close()

# Convert all of the input values from strings to floats (把输入的值转换为浮点数)
fvalues = [float(s) for s in svalues]

# Print min and max values (输出最大值和最小值)
print "The minimum value is ", min(fvalues)
print "The maximum value is ", max(fvalues)
}}}
程序第一行用import语句从Python library中导入sys模块。

你需要在命令行提供一个文件名给上面的程序,该文件名参数保存在sys.argv 列表中,open方法通过读取sys.argv[1]得到这个文件名参数。

readlines()方法读取文件中的所有的行到一个列表中。

表达式 [float(s) for s in svalues] 通过循环列表svalues中的所有字符串并对每个元素运行函数float()来建立一个新的列表,这种特殊的建立列表的方法叫做列表包含( list comprehension)。
在列表中所有的字符串都转换为浮点数之后,内建函数min()和max()计算出列表中的最大值及最小值。

元组(tuple)类型和列表关系很密切,通过用圆括号中将一系列逗号分割的值括起来可以得到一个元组:
{{{#!python
a = (1,4,5,-9,10)
b = (7,) # 一个元素的元组 (注意一定要加一个额外的逗号!)
person = (first_name, last_name, phone)
}}}
在某些时候,即使没有圆括号, Python仍然可以根据上下文认出这是一个元组,如: (为了写出更清晰可读的程序,建议你不要依赖 Python 的智能)
{{{
a = 1,4,5,-9,10
b = 7,
person = first_name, last_name, phone
}}}
元组支持大多数列表的操作,比如索引,切片和连结。一个关键的不同是你不能在一个tuple创建之后修改它的内容。也就是说,你不能修改其中的元素,也不能给tuple添加新的元素。

== 循环 ==

通过使用while语句,我们在前面已经简单介绍了 while 循环。在Python中另一种循环结构是 for 循环,它通过 迭代 一个序列(例如字符串,列表,或者tuple等)中的每个元素来建立循环。下边是一个例子:
{{{
for i in range(1,10):
        print "2 to the %d power is %d" % (i, 2**i)
}}}
range(i,j)函数建立一个整数序列,这个序列从第 i 数开始(包括 i )到第 j 数为止(不包括 j)。若第一个数被省略,它将被认为是0。该函数还可以有第三个参数,步进值,见下面的例子:
{{{
a = range(5) # a = [0,1,2,3,4]
b = range(1,8) # b = [1,2,3,4,5,6,7]
c = range(0,14,3) # c = [0,3,6,9,12]
d = range(8,1,-1) # d = [8,7,6,5,4,3,2]
}}}
for语句可以迭代任何类型的序列:
{{{
a = "Hello World"
# Print out the characters in a
for c in a:
        print c
b = ["Dave","Mark","Ann","Phil"]
# Print out the members of a list
for name in b:
        print name
}}}
range()函数根据起始值,终止值及步进值三个参数在内存中建立一个列表,当需要一个很大的列表时,这个既占内存又费时间。为了克服它的缺点,Python提供了xrange()函数:
{{{
for i in xrange(1,10):
        print "2 to the %d power is %d" % (i, 2**i)

a = xrange(100000000) # a = [0,1,2, ..., 99999999]
b = xrange(0,100000000,5) # b = [0,5,10, ...,99999995]
}}}
xrange()函数只有在需要值时才临时通过计算提供值,这大大节省了内存。

== 字典 ==

字典就是一个关联数组(或称为哈希表)。它是一个通过关键字索引的对象的集合。使用大括号{}来创建一个字典,如下 例:
{{{
a = {
       "username" : "beazley",
       "home" : "/home/beazley",
       "uid" : 500
    }

用关键字索引操作符可以访问字典的某个特定值:

u = a["username"]
d = a["home"]

用下面的方式插入或者修改对象:

a["username"] = "pxl"
a["home"] = "/home/pxl"
a["shell"] = "/usr/bin/tcsh"
}}}
尽管字符串是最常见的 关键字(key) 类型,你还是可以使用很多其它的 python 对象做为字典的关键字,比如 数字 和 tuple,只要是不可修改对象,都可以用来做字典的key。有些对象,例如列表和字典,不可以用来做字典的key,因为他们的内容是允许更改的。

我们可以使用 has_key() 方法来检验一个键/值对是否存在(或者in操作符):
{{{
if a.has_key("username"):
     username = a["username"]
else:
     username = "unknown user"

上边的操作还可以用更简单的方法完成:

username = a.get("username", "unknown user")

字典的keys() 方法返回由所有关键字组成的列表:

k = a.keys() # k = ["username","home","uid","shell"]

del语句可以删除字典中的特定元素:

del a["username"]
}}}

[:WeiZhong/2006-01-17:Python 精要参考(第二版)] Python Essential Reference, Second Edition 译文

原著:David M Beazley 出版商: New Riders Publishing

初译: Feather andelf@gmail,com 修正补充: WeiZhong weizhong2004@gmail,com TableOfContents

第二章 语法及代码约定

本章讲述了Python程序的语法和代码约定。 本章的主题有行结构,语句分组,保留字,字符串,运算符,token等等,另外对如何使用 Unicode 字符串也做了详细的描述。

行结构/缩进

程序中的每个语句都以换行符结束。特别长的语句可以使用续行符(\)来分成几个短小的行,如下例:

import math
a = math,cos(3*(x-n)) + \
    math,sin(3*(y-n))

当你定义一个三引号字符串、列表、tuple 或者字典的时候不需要续行符来分割语句。及就是说,在程序中,凡是圆括号(,,,)、方括号[,,,]、花括号{,,,}及三引号字符串内的部分均不需要使用续行符。

缩进被用来指示不同的代码块,比如函数的主体代码块,条件执行代码块,循环体代码块及类定义代码块。缩进的空格(制表符)数目可以是任意的,但是在整个块中的缩进必须一致:

   1 if a:
   2    statement1     # 缩进一致,正确!
   3    statement2
   4 else:
   5    statement3
   6      statement4   #缩进不一致,错误!

如果块中只有很少的语句,那么你也可以把它们放置在同一行:

if a:  statement1
else:  statement2

要表示一个空的块或是空的主体,使用 pass语句:

if a:
   pass
else:
   statements

尽管允许用制表符指示缩进,我还是要说这是一个不好的习惯。 坚决不要混合使用制表符和空格来缩进,这会给你带来意想不到的麻烦。建议你在每个缩进层次中使用单个制表符或两个或四个空格。运行 Python的时候使用 -t 参数,如果python 发现存在制表符和空格混用,它就显示警告信息,若使用 -tt 参数 python 则会在遇到混用情况时引发TabError异常。

分号(;)可以把多个语句放在同一行中,只有一个语句的行也可以用分号来结束。

#指示这是一个延长至行末的注释,但是包在字符串内的#没有这个功能。

最后要说明的,解释器会忽略所有的空白行(非交互模式下)。

标识符及保留字

标识符是用于识别变量、函数、类、模块以及其他对象的名字,标识符可以包含字母、数字及下划线(_),但是必须以一个非数字字符开始。字母仅仅包括ISO-Latin字符集中的A–Z和a–z。标识符是大小写敏感的,因此 FOO和foo是两个不同的对象。特殊符号,如$、%、@等,不能用在标识符中。另外,如 if,else,for 等单词是保留字,也不能将其用作标识符。下面的表列出了所有的保留字符:

and             elif                    global                  or
assert                  else                    if                      pass
break                   except                  import                  print
class                   exec                    in                      raise
continue                finally                 is                      return
def                     for                     lambda                  try
del                     from                    not                     while

以下划线开始或者结束的标识符通常有特殊的意义。例如以一个下划线开始的标识符(如 _foo)不能用from module import *语句导入。前后均有两个下划线的标识符,如init,被特殊方法保留。前边有两个下划线的标识符,如bar,被用来实现类私有属性,这个将在第七章--类与面向对象编程中讲到。通常情况下,应该避免使用相似的标识符。

数字/文字

Python中有四种内建的数值类型:整数、长整数、浮点数和复数。

象1234这样的数被解析为一个十进制的整数。要指定一个八进制或者十六进制的整数,在一个合法的八进制数前加上 0 或者在一个合法的16进制数前加上 0x 就可以了。(如 0644 和 0x100fea8)。 在一个整数后面加上字母 l 或 L系统就认为这是一个长整数(如 1234567890L)。与受机器字长限制整数类型不同,长整数可以是任何长度(只受内存大小限制)。象123.34和1.2334e+02这样的数被解析为浮点数。一个整数或者浮点数加上后缀 J 或者 j 就构成了一个复数的虚部,你可以用一个实数加上一个虚部创建一个复数,比如 1.2 + 12.34J。

Python目前支持两种类型的字符串:

8位字符数据 (ASCII)

16位宽字符数据 (Unicode)

最常用的是ASCII字符串,因为这个字符集刚好只用一个字节就可以字符集中的任意一个字符。通常情况下,ASCII串用单引号('),双引号("),或者三引号( 或 """)来定义。字符串前后的引号类型必须一致。反斜杠(\)用来转义特殊字符,比如换行符、反斜杠本身、引号以及其他非打印字符。Table 2.1中列出了公认的特殊字符的表示方法,无法识别的转义字符串将被原样保留(包括前边的反斜杠)。此外,字符串可以包含嵌入的空字节和二进制数据。三引号字符串中可以包含不必转义的换行符和引号。

Table 2.1 Standard Character Escape Codes

标准特殊字符

字符

描述

\

续行符

\\

反斜杠

\'

单引号

\"

双引号

\a

Bell(音箱发出吡的一声)

\b

退格符

\e

Escape

\0

Null(空值)

\n

换行符,等价于\x0a和\cJ

\v

垂直制表符,等价于\x0b和\cK

\t

水平制表符,等价于\x09和\cI

\r

回车符,等价于\x0d和\cM

\f

换页符,等价于\x0c和\cL

\OOO

八进制值(000-377)

\xhh

十六进制值(x00-xff)

\un

Unicode字符值,n是四个十六进制数字表示的Unicode字符

Unicode 字符串用来表示多字节国际字符集,它包括65,536个字符。Unicode字符使用u或者U前缀来定义,例如`a = u"hello"`。在Unicode字符集中,每一个字符用一个16位整数来表示。Unicode字符使用 U+XXXX 这种形式来表示,XXXX是一个由 4 个十六进制数字组成的16进制数。(注意: 这种记法只是一个表示Unicode字符的习惯,并不是Python的语法)。例如U+0068是Unicode字符字母h(在Latin-1字符集中,你可以发现Unicode字符集的前256个字符与Lation-1的对应字符编码完全相同)。当Unicode字符串被赋值时普通字符和特殊字符都直接转换成Unicode字符序数(在[U+0000, U+00FF]中)。例如,字符串"hello\n"映射为ASCII时是:0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a,当使用u"hello\n"转换为Unicode字符串时是:U+0068, U+0065, U+006C, U+006C, U+006F, U+000A.任意Unicode字符都可以使用\uXXXX来定义,\uXXXX必须位于一个Unicode字符串中,例如:

s = u"\u0068\u0065\u006c\u006c\u006f\u000a"

在Python 的较老版本中,\xXXXX字节序列被用来定义Unicode字符(这与系统识别Unicode字符方式有关)。虽然现在仍然允许这样做,我仍然建议你最好采用新的表示方法。(因为旧的表示方法随时可能废止。)另外,八进制代码\OOO也可以用来定义在[U+0000, U+01FF]中的Unicode字符。

Unicode字符不能通过使用 UTF-8或者UTF-16编码中的原始字节序列来定义。例如,UTF-8编码的字符串 u'M\303\274ller' 建立的七个字符,用Unicode表示为+004D, U+00C3, U+00BC, U+006C, U+006C, U+0065, U+0072,这并不是你想要的结果。这是因为在UTF-8中,多字节序列\303\274用来代表U+00FC,而不是U+00C3, U+00BC。更多关于Unicode编码细节你可以阅读第三章--"类型和对象",第四章--"运算符和表达式",第九章--"输入和输出".

你可以给一个字符串加上前缀r或者R,例如 `r'\n\"'`,这些字符串被称为原始字符串,因为里边几乎所有的特殊字符都会原封不动地留下。不过原始字符串并不能以一个单独的反斜杠结尾(例如 r"\")。如果原始字符串使用ur或者UR前缀来定义的话,\uXXXX仍然会被解析为Unicode字符。如果你不想这样,你可以在它前边再加一个反斜杠,例如ur"\\u1234",它定义了一个含有7个字符的字符串。需要注意的是,定义原始Unicode字符串时,r必须在u之后。

邻近的字符串(被空格或者续行符分割),例如 "hello" 'world' 会被Python自动连结为一个字符串 "helloworld"。无论是普通字符串,Unicode字符串,还是自然字符串,都会自动连结。当然,只要这些字符串中有一个是Unicode字符串,那最终连结的结果也将是一个Unicode字符串。比如 "s1" u"s2" 就会产生 u"s1s2"。这个过程的细节你可以阅读第四章和附录A(the Python library).

如果Python在 -U 命令行参数下运行,所有的字符都会被解析为Unicode。

方括号[...]定义一个列表,圆括号(...)定义一个元组,花括号{...}定义一个字典:

 a = [ 1, 3.4, 'hello' ]           # A list
 b = ( 10, 20, 30 )                # A tuple
 c = { 'a': 3, 'b':42 }            # A dictionary 

WeiZhong/2006-01-17 (last edited 2009-12-25 07:17:10 by localhost)