最近一直在研究python。。。

自学了一段时间,感觉对我这种本身脑子转不过弯的人来是真心是个不错的选择。。

以下是自己学习总结的笔记,有需要的朋友可以用来参考。


系统版本: Centos6.3 x64

PYTHON:   Python 2.6.6


1.安装python(centos默认自带)

# yum install python -y


=============================


1.1 查看python版本

# python -V

-------------

Python 2.6.6

-------------


==============================


1.2 使用带提示符的python解释器

# python

------------------------

Python 2.6.6 (r266:84292, Jun 18 2012, 14:18:47)

[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> print 'hello world'

hello world

>>>

------------------------

退出: Ctrl-d


=============================


1.3 使用源文件

# vi helloworld.py

--------------------------

#!/usr/bin/python

# Filename : helloworld.py

print 'Hello World'

--------------------------

输出:

$ python helloworld.py

-------------------

Hello World

-------------------


可执行的Python程序


$ chmod a+x helloworld.py

$ ./helloworld.py

----------

Hello World

----------


=============================


1.4 获取帮助


如果你需要某个Python函数或语句的快速信息帮助,那么你可以使用内建的help功能。尤其在你使用带提示符的命令行的时候,它十分有用。比如,运行help(str)——这会显示str类的帮助。str类用于保存你的程序使用的各种文本(字符串)。类将在后面面向对象编程的章节详细解释。


注释

按q退出帮助。

类似地,你可以获取Python中几乎所有东西的信息。使用help()去学习更多关于help本身的东西!


如果你想要获取关于如print那样操作符的帮助,那么你需要正确的设置PYTHONDOCS环境变量。这可以在Linux/Unix中轻松地通过env命令完成。


# env PYTHONDOCS=/usr/share/doc/python-docs-2.3.4/html/ python

------------------------------------

Python 2.6.6 (r266:84292, Jun 18 2012, 14:18:47)

[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> help('print')

-------------------------------------

你应该注意到我特意在“print”上使用了引号,那样Python就可以理解我是希望获取关于“print”的帮助而不是想要它打印东西。



====================================


2.数


在Python中有4种类型的数——整数、长整数、浮点数和复数。


2是一个整数的例子。

长整数不过是大一些的整数。

3.23和52.3E-4是浮点数的例子。E标记表示10的幂。在这里,52.3E-4表示52.3 * 10-4。

(-5+4j)和(2.3-4.6j)是复数的例子。


=====================================


3.字符串


字符串是字符的序列 。字符串基本上就是一组单词。


使用单引号(')

你可以用单引号指示字符串,就如同'Quote me on this'这样。所有的空白,即空格和制表符都照原样保留。


使用双引号(")

在双引号中的字符串与单引号中的字符串的使用完全相同,例如"What's your name?"。


使用三引号('''或""")

利用三引号,你可以指示一个多行的字符串。你可以在三引号中自由的使用单引号和双引号。

例如:

-----------------------

'''This is a multi-line string. This is the first line.

This is the second line.

"What's your name?," I asked.

He said "Bond, James Bond."

'''

------------------------


转义符


假设你想要在一个字符串中包含一个单引号('),那么你该怎么指示这个字符串?例如,这个字符串是What's your name?。你肯定不会用'What's your name?'来指示它,因为Python会弄不明白这个字符串从何处开始,何处结束。所以,你需要指明单引号而不是字符串的结尾。可以通过 转义符 来完成这个任务。你用\'来指示单引号——注意这个反斜杠。现在你可以把字符串表示为'What\'s your name?'。


另一个表示这个特别的字符串的方法是"What's your name?",即用双引号。类似地,要在双引号字符串中使用双引号本身的时候,也可以借助于转义符。另外,你可以用转义符\\来指示反斜杠本身。


值得注意的一件事是,在一个字符串中,行末的单独一个反斜杠表示字符串在下一行继续,而不是开始一个新的行。

例如:

--------------------------

"This is the first sentence.\

This is the second sentence."

等价于"This is the first sentence. This is the second sentence."

--------------------------


自然字符串


如果你想要指示某些不需要如转义符那样的特别处理的字符串,那么你需要指定一个自然字符串。自然字符串通过给字符串加上前缀r或R来指定。例如r"Newlines are indicated by \n"。


Unicode字符串


Unicode是书写国际文本的标准方法。如果你想要用你的母语如北印度语或阿拉伯语写文本,那么你需要有一个支持Unicode的编辑器。类似地,Python允许你处理Unicode文本——你只需要在字符串前加上前缀u或U。例如,u"This is a Unicode string."。


记住,在你处理文本文件的时候使用Unicode字符串,特别是当你知道这个文件含有用非英语的语言写的文本。


字符串是不可变的


这意味着一旦你创造了一个字符串,你就不能再改变它了。虽然这看起来像是一件坏事,但实际上它不是。我们将会在后面的程序中看到为什么我们说它不是一个缺点。


按字面意义级连字符串


如果你把两个字符串按字面意义相邻放着,他们会被Python自动级连。例如,'What\'s' 'your name?'会被自动转为"What's your name?"。


===============================


4.变量


仅仅使用字面意义上的常量很快就会引发烦恼——我们需要一种既可以储存信息 又可以对它们进行操作的方法。这是为什么要引入 变量 。变量就是我们想要的东西——它们的值可以变化,即你可以使用变量存储任何东西。变量只是你的计算机中存储信息的一部分内存。与字面意义上的常量不同,你需要一些能够访问这些变量的方法,因此你给变量名字。


==============================


4.1 标识符的命名


变量是标识符的例子。 标识符 是用来标识 某样东西 的名字。在命名标识符的时候,你要遵循这些规则:


标识符的第一个字符必须是字母表中的字母(大写或小写)或者一个下划线(‘ _ ’)。


标识符名称的其他部分可以由字母(大写或小写)、下划线(‘ _ ’)或数字(0-9)组成。


标识符名称是对大小写敏感的。例如,myname和myName不是一个标识符。注意前者中的小写n和后者中的大写N。


有效 标识符名称的例子有i、__my_name、name_23和a1b2_c3。


无效 标识符名称的例子有2things、this is spaced out和my-name。


==============================


4.2 数据类型


变量可以处理不同类型的值,称为数据类型。基本的类型是数和字符串,我们已经讨论过它们了。在后面的章节里面,我们会研究怎么用类创造我们自己的类型。


==============================


5.对象


记住,Python把在程序中用到的任何东西都称为 对象 。这是从广义上说的。因此我们不会说“某某 东西 ”,我们说“某个 对象 ”。


给面向对象编程用户的注释

就每一个东西包括数、字符串甚至函数都是对象这一点来说,Python是极其完全地面向对象的。

我们将看一下如何使用变量和字面意义上的常量。保存下面这个例子,然后运行程序。


如何编写Python程序

下面是保存和运行Python程序的标准流程。

  1. 打开你最喜欢的编辑器。

  2. 输入例子中的程序代码。

  3. 用注释中给出的文件名把它保存为一个文件。我按照惯例把所有的Python程序都以扩展名.py保存。

  4. 运行解释器命令python program.py或者使用IDLE运行程序。你也可以使用先前介绍的可执行的方法。


使用变量和字面意义上的常量

----------------------------

# Filename : var.py

i = 5

print i

i = i + 1

print i


s = '''This is a multi-line string.

This is the second line.'''

print s

------------------------------


输出


$ python var.py

------------------

5

6

This is a multi-line string.

This is the second line.

------------------

它如何工作


下面来说明一下这个程序如何工作。首先我们使用赋值运算符(=)把一个字面意义上的常数5赋给变量i。这一行称为一个语句。语句声明需要做某件事情,在这个地方我们把变量名i与值5连接在一起。接下来,我们用print语句打印i的值,就是把变量的值打印在屏幕上。


然后我们对i中存储的值加1,再把它存回i。我们打印它时,得到期望的值6。


类似地,我们把一个字面意义上的字符串赋给变量s然后打印它。


===================================


5.2 输出标识符的命名


变量是标识符的例子。 标识符 是用来标识 某样东西 的名字。在命名标识符的时候,你要遵循这些规则:


标识符的第一个字符必须是字母表中的字母(大写或小写)或者一个下划线(‘ _ ’)。


标识符名称的其他部分可以由字母(大写或小写)、下划线(‘ _ ’)或数字(0-9)组成。


标识符名称是对大小写敏感的。例如,myname和myName不是一个标识符。注意前者中的小写n和后者中的大写N。


有效 标识符名称的例子有i、__my_name、name_23和a1b2_c3。


无效 标识符名称的例子有2things、this is spaced out和my-name。


=============================


5.3 缩进


空白在Python中是重要的。事实上行首的空白是重要的。它称为缩进。在逻辑行首的空白(空格和制表符)用来决定逻辑行的缩进层次,从而用来决定语句的分组。


这意味着同一层次的语句必须有相同的缩进。每一组这样的语句称为一个块。我们将在后面的章节中看到有关块的用处的例子。


你需要记住的一样东西是错误的缩进会引发错误。例如:

------------------------------

i = 5

print 'Value is', i # Error! Notice a single space at the start of the line

print 'I repeat, the value is', i

------------------------------

当你运行这个程序的时候,你会得到下面的错误:

------------------------------

 File "whitespace.py", line 4

   print 'Value is', i # Error! Notice a single space at the start of the line

   ^

SyntaxError: invalid syntax

-------------------------------

注意,在第二行的行首有一个空格。Python指示的这个错误告诉我们程序的语法是无效的,即程序没有正确地编写。它告诉你, 你不能随意地开始新的语句块 (当然除了你一直在使用的主块)。何时你能够使用新块,将会在后面的章节,如控制流中详细介绍。


==================================


5.4 运算符与它们的用法


运算符名称说明

+两个对象相加

-得到负数或是一个数减去另一个数

*两个数相乘或是返回一个被重复若干次的字符串

**返回x的y次幂

/x除以y

//取整除返回商的整数部分

%取模返回除法的余数

<<左移把一个数的比特向左移一定数目(每个数在内存中都表示为比特或二进制数字,即0和1)  2 << 2得到8。——2按比特表示为10

>>右移把一个数的比特向右移一定数目 11 >> 1得到5。——11按比特表示为1011,向右移动1比特后得到101,即十进制的5。

&按位与数的按位与 5 & 3得到1。

|按位或数的按位或 5 | 3得到7。

^按位异或数的按位异或 5 ^ 3得到6

~按位翻转x的按位翻转是-(x+1) ~5得到-6。

<小于返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。

>大于返回x是否大于y

<=小于等于返回x是否小于等于y

>=大于等于返回x是否大于等于y

==等于比较对象是否相等

!=不等于比较两个对象是否不相等

not布尔“非”如果x为True,返回False。如果x为False,它返回True。

and布尔“与”如果x为False,x and y返回False,否则它返回y的计算值。

or布尔“或”如果x是True,它返回True,否则它返回y的计算值。



=========================================



5.5 运算符优先级


如果你有一个如2 + 3 * 4那样的表达式,是先做加法呢,还是先做乘法?我们的中学数学告诉我们应当先做乘法——这意味着乘法运算符的优先级高于加法运算符。


下面这个表给出Python的运算符优先级,从最低的优先级(最松散地结合)到最高的优先级(最紧密地结合)。这意味着在一个表达式中,Python会首先计算表中较下面的运算符,然后在计算列在表上部的运算符。


下面这张表(与Python参考手册中的那个表一模一样)已经顾及了完整的需要。事实上,我建议你使用圆括号来分组运算符和操作数,以便能够明确地指出运算的先后顺序,使程序尽可能地易读。例如,2 + (3 * 4)显然比2 + 3 * 4清晰。与此同时,圆括号也应该正确使用,而不应该用得过滥(比如2 + (3 + 4))。


运算符优先级


运算符描述

lambdaLambda表达式

or布尔“或”

and布尔“与”

not x布尔“非”

in,not in成员测试

is,is not同一性测试

<,<=,>,>=,!=,==比较

|按位或

^按位异或

&按位与

<<,>>移位

+,-加法与减法

*,/,%乘法、除法与取余

+x,-x正负号

~x按位翻转

**指数

x.attribute属性参考

x[index]下标

x[index:index]寻址段

f(arguments...)函数调用

(experession,...)绑定或元组显示

[expression,...]列表显示

{key:datum,...}字典显示

'expression,...'字符串转换

其中我们还没有接触过的运算符将在后面的章节中介绍。


在表中列在同一行的运算符具有 相同优先级 。例如,+和-有相同的优先级。


计算顺序


默认地,运算符优先级表决定了哪个运算符在别的运算符之前计算。然而,如果你想要改变它们的计算顺序,你得使用圆括号。例如,你想要在一个表达式中让加法在乘法之前计算,那么你就得写成类似(2 + 3) * 4的样子。


结合规律


运算符通常由左向右结合,即具有相同优先级的运算符按照从左向右的顺序计算。例如,2 + 3 + 4被计算成(2 + 3) + 4。一些如赋值运算符那样的运算符是由右向左结合的,即a = b = c被处理为a = (b = c)。


======================================


5.6 使用变量和字面意义上的常量

------------------------------

# Filename : var.py

i = 5

print i

i = i + 1

print i


s = '''This is a multi-line string.

This is the second line.'''

print s

-------------------------------

输出


$ python var.py

-----------------

5

6

This is a multi-line string.

This is the second line.

-----------------


======================================


6.使用表达式

------------------------

#!/usr/bin/python

# Filename: expression.py


length = 5

breadth = 2

area = length * breadth

print 'Area is', area

print 'Perimeter is', 2 * (length + breadth)

-------------------------


输出


$ python expression.py

----------------

Area is 10

Perimeter is 14

----------------


======================================


6.1 if语句


if语句用来检验一个条件, 如果 条件为真,我们运行一块语句(称为 if-块 ), 否则 我们处理另外一块语句(称为 else-块 )。 else 从句是可选的。


使用if语句

----------------------------

#!/usr/bin/python

# Filename: if.py


number = 23

guess = int(raw_input('Enter an integer : '))


if guess == number:

   print 'Congratulations, you guessed it.' # New block starts here

   print "(but you do not win any prizes!)" # New block ends here

elif guess < number:

   print 'No, it is a little higher than that' # Another block

   # You can do whatever you want in a block ...

else:

   print 'No, it is a little lower than that'

   # you must have guess > number to reach here


print 'Done'

# This last statement is always executed, after the if statement is executed

-----------------------------


输出


$ python if.py

-------------------------

Enter an integer : 50

No, it is a little lower than that

Done

-------------------------

$ python if.py

----------------------

Enter an integer : 22

No, it is a little higher than that

Done

----------------------

$ python if.py

----------------------

Enter an integer : 23

Congratulations, you guessed it.

(but you do not win any prizes!)

Done

---------------------


它如何工作


在这个程序中,我们从用户处得到猜测的数,然后检验这个数是否是我们手中的那个。我们把变量number设置为我们想要的任何整数,在这个例子中是23。然后,我们使用raw_input()函数取得用户猜测的数字。函数只是重用的程序段。我们将在下一章学习更多关于函数的知识。


我们为内建的raw_input函数提供一个字符串,这个字符串被打印在屏幕上,然后等待用户的输入。一旦我们输入一些东西,然后按回车键之后,函数返回输入。对于raw_input函数来说是一个字符串。我们通过int把这个字符串转换为整数,并把它存储在变量guess中。事实上,int是一个类,不过你想在对它所需了解的只是它把一个字符串转换为一个整数(假设这个字符串含有一个有效的整数文本信息)。


接下来,我们将用户的猜测与我们选择的数做比较。如果他们相等,我们打印一个成功的消息。注意我们使用了缩进层次来告诉Python每个语句分别属于哪一个块。这就是为什么缩进在Python如此重要的原因。我希望你能够坚持“每个缩进层一个制表符”的规则。你是这样的吗?


注意if语句在结尾处包含一个冒号——我们通过它告诉Python下面跟着一个语句块。


然后,我们检验猜测是否小于我们的数,如果是这样的,我们告诉用户它的猜测大了一点。我们在这里使用的是elif从句,它事实上把两个相关联的if else-if else语句合并为一个if-elif-else语句。这使得程序更加简单,并且减少了所需的缩进数量。


elif和else从句都必须在逻辑行结尾处有一个冒号,下面跟着一个相应的语句块(当然还包括正确的缩进)。


你也可以在一个if块中使用另外一个if语句,等等——这被称为嵌套的if语句。


记住,elif和else部分是可选的。一个最简单的有效if语句是:


if True:

   print 'Yes, it is true'

在Python执行完一个完整的if语句以及与它相关联的elif和else从句之后,它移向if语句块的下一个语句。在这个例子中,这个语句块是主块。程序从主块开始执行,而下一个语句是print 'Done'语句。在这之后,Python看到程序的结尾,简单的结束运行。


尽管这是一个非常简单的程序,但是我已经在这个简单的程序中指出了许多你应该注意的地方。所有这些都是十分直接了当的(对于那些拥有C/C++背景的用户来说是尤为简单的)。它们在开始时会引起你的注意,但是以后你会对它们感到熟悉、“自然”。


==============================



6.2 while语句


只要在一个条件为真的情况下,while语句允许你重复执行一块语句。while语句是所谓 循环 语句的一个例子。while语句有一个可选的else从句。


使用while语句


----------------------------

#!/usr/bin/python

# Filename: while.py


number = 23

running = True


while running:

   guess = int(raw_input('Enter an integer : '))


   if guess == number:

       print 'Congratulations, you guessed it.'

       running = False # this causes the while loop to stop

   elif guess < number:

       print 'No, it is a little higher than that'

   else:

       print 'No, it is a little lower than that'

else:

   print 'The while loop is over.'

   # Do anything else you want to do here


print 'Done'

--------------------------


输出


$ python while.py

------------------------------

Enter an integer : 50

No, it is a little lower than that.

Enter an integer : 22

No, it is a little higher than that.

Enter an integer : 23

Congratulations, you guessed it.

The while loop is over.

Done

----------------------------


它如何工作


在这个程序中,我们仍然使用了猜数游戏作为例子,但是这个例子的优势在于用户可以不断的猜数,直到他猜对为止——这样就不需要像前面那个例子那样为每次猜测重复执行一遍程序。这个例子恰当地说明了while语句的使用。


我们把raw_input和if语句移到了while循环内,并且在while循环开始前把running变量设置为True。首先,我们检验变量running是否为True,然后执行后面的 while-块 。在执行了这块程序之后,再次检验条件,在这个例子中,条件是running变量。如果它是真的,我们再次执行while-块,否则,我们继续执行可选的else-块,并接着执行下一个语句。


当while循环条件变为False的时候,else块才被执行——这甚至也可能是在条件第一次被检验的时候。如果while循环有一个else从句,它将始终被执行,除非你的while循环将永远循环下去不会结束!


True和False被称为布尔类型。你可以分别把它们等效地理解为值1和0。在检验重要条件的时候,布尔类型十分重要,它们并不是真实的值1。


else块事实上是多余的,因为你可以把其中的语句放在同一块(与while相同)中,跟在while语句之后,这样可以取得相同的效果。



====================================


6.3 for循环


for..in是另外一个循环语句,它在一序列的对象上 递归 即逐一使用队列中的每个项目。我们会在后面的章节中更加详细地学习序列。


使用for语句


-----------------------------

#!/usr/bin/python

# Filename: for.py


for i in range(1, 5):

   print i

else:

   print 'The for loop is over'

------------------------------

输出


$ python for.py

-----------------

1

2

3

4

The for loop is over

------------------

它如何工作


在这个程序中,我们打印了一个 序列 的数。我们使用内建的range函数生成这个数的序列。


我们所做的只是提供两个数,range返回一个序列的数。这个序列从第一个数开始到第二个数为止。例如,range(1,5)给出序列[1, 2, 3, 4]。默认地,range的步长为1。如果我们为range提供第三个数,那么它将成为步长。例如,range(1,5,2)给出[1,3]。记住,range 向上 延伸到第二个数,即它不包含第二个数。


for循环在这个范围内递归——for i in range(1,5)等价于for i in [1, 2, 3, 4],这就如同把序列中的每个数(或对象)赋值给i,一次一个,然后以每个i的值执行这个程序块。在这个例子中,我们只是打印i的值。


记住,else部分是可选的。如果包含else,它总是在for循环结束后执行一次,除非遇到break语句。


记住,for..in循环对于任何序列都适用。这里我们使用的是一个由内建range函数生成的数的列表,但是广义说来我们可以使用任何种类的由任何对象组成的序列!我们会在后面的章节中详细探索这个观点。

---------------------------


=================================


6.4 break语句


break语句是用来 终止 循环语句的,即哪怕循环条件没有称为False或序列还没有被完全递归,也停止执行循环语句。


一个重要的注释是,如果你从for或while循环中 终止 ,任何对应的循环else块将不执行。


使用break语句


-----------------------

#!/usr/bin/python

# Filename: break.py


while True:

   s = raw_input('Enter something : ')

   if s == 'quit':

       break

   print 'Length of the string is', len(s)

print 'Done'

------------------------


输出


$ python break.py

--------------------------

Enter something : Programming is fun

Length of the string is 18

Enter something : When the work is done

Length of the string is 21

Enter something : if you wanna make your work also fun:

Length of the string is 37

Enter something :       use Python!

Length of the string is 12

Enter something : quit

Done

--------------------------

它如何工作


在这个程序中,我们反复地取得用户地输入,然后打印每次输入地长度。我们提供了一个特别的条件来停止程序,即检验用户的输入是否是'quit'。通过 终止 循环到达程序结尾来停止程序。


输入字符串的长度通过内建的len函数取得。


记住,break语句也可以在for循环中使用。


G2的Python诗


我在这里输入的是我所写的一段小诗,称为G2的Python诗:

-----------------------

Programming is fun

When the work is done

if you wanna make your work also fun:

     use Python!

-----------------------



===============================


6.5 continue语句


continue语句被用来告诉Python跳过当前循环块中的剩余语句,然后 继续 进行下一轮循环。


使用continue语句


----------------------------

#!/usr/bin/python

# Filename: continue.py


while True:

   s = raw_input('Enter something : ')

   if s == 'quit':

       break

   if len(s) < 3:

       continue

   print 'Input is of sufficient length'

   # Do other kinds of processing here...

----------------------------


输出


$ python continue.py

----------------------------

Enter something : a

Enter something : 12

Enter something : abc

Input is of sufficient length

Enter something : quit

----------------------------


它如何工作


在这个程序中,我们从用户处取得输入,但是我们仅仅当它们有至少3个字符长的时候才处理它们。所以,我们使用内建的len函数来取得长度。如果长度小于3,我们将使用continue语句忽略块中的剩余的语句。否则,这个循环中的剩余语句将被执行,我们可以在这里做我们希望的任何处理。


注意,continue语句对于for循环也有效。


=============================


7.函数


函数是重用的程序段。它们允许你给一块语句一个名称,然后你可以在你的程序的任何地方使用这个名称任意多次地运行这个语句块。这被称为 调用 函数。我们已经使用了许多内建的函数,比如len和range。


函数通过def关键字定义。def关键字后跟一个函数的 标识符 名称,然后跟一对圆括号。圆括号之中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它们是函数体。下面这个例子将说明这事实上是十分简单的:



7.1 定义函数

-------------------------

#!/usr/bin/python

# Filename: function1.py


def sayHello():

   print 'Hello World!' # block belonging to the function


sayHello() # call the function

-------------------------


输出


$ python function1.py

---------------

Hello World!

---------------

它如何工作


我们使用上面解释的语法定义了一个称为sayHello的函数。这个函数不使用任何参数,因此在圆括号中没有声明任何变量。参数对于函数而言,只是给函数的输入,以便于我们可以传递不同的值给函数,然后得到相应的结果。



=============================


7.2 使用函数形参


函数取得的参数是你提供给函数的值,这样函数就可以利用这些值 做 一些事情。这些参数就像变量一样,只不过它们的值是在我们调用函数的时候定义的,而非在函数本身内赋值。


参数在函数定义的圆括号对内指定,用逗号分割。当我们调用函数的时候,我们以同样的方式提供值。注意我们使用过的术语——函数中的参数名称为 形参 而你提供给函数调用的值称为 实参 。

----------------------------

#!/usr/bin/python

# Filename: func_param.py


def printMax(a, b):

   if a > b:

       print a, 'is maximum'

   else:

       print b, 'is maximum'


printMax(3, 4) # directly give literal values


x = 5

y = 7


printMax(x, y) # give variables as arguments

----------------------------


输出


$ python func_param.py

--------------------------

4 is maximum

7 is maximum

-------------------------

它如何工作


这里,我们定义了一个称为printMax的函数,这个函数需要两个形参,叫做a和b。我们使用if..else语句找出两者之中较大的一个数,并且打印较大的那个数。


在第一个printMax使用中,我们直接把数,即实参,提供给函数。在第二个使用中,我们使用变量调用函数。printMax(x, y)使实参x的值赋给形参a,实参y的值赋给形参b。在两次调用中,printMax函数的工作完全相同。


===================================


7.3 使用局部变量


当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的。这称为变量的 作用域 。所有变量的作用域是它们被定义的块,从它们的名称被定义的那点开始。


----------------------------

#!/usr/bin/python

# Filename: func_local.py


def func(x):

   print 'x is', x

   x = 2

   print 'Changed local x to', x


x = 50

func(x)

print 'x is still', x

----------------------------


注:这里在func(x)变量内的内容必须互相对其才能生效,如果未对齐表示其非变量内容


输出


$ python func_local.py

----------------------

x is 50

Changed local x to 2

x is still 50

----------------------


它如何工作


在函数中,我们第一次使用x的 值 的时候,Python使用函数声明的形参的值。


接下来,我们把值2赋给x。x是函数的局部变量。所以,当我们在函数内改变x的值的时候,在主块中定义的x不受影响。


在最后一个print语句中,我们证明了主块中的x的值确实没有受到影响。


=================================


7.4 使用global语句


如果你想要为一个定义在函数外的变量赋值,那么你就得告诉Python这个变量名不是局部的,而是 全局 的。我们使用global语句完成这一功能。没有global语句,是不可能为定义在函数外的变量赋值的。


你可以使用定义在函数外的变量的值(假设在函数内没有同名的变量)。然而,我并不鼓励你这样做,并且你应该尽量避免这样做,因为这使得程序的读者会不清楚这个变量是在哪里定义的。使用global语句可以清楚地表明变量是在外面的块定义的。

-------------------------------

#!/usr/bin/python

# Filename: func_global.py


def func():

   global x


   print 'x is', x

   x = 2

   print 'Changed local x to', x


x = 50

func()

print 'Value of x is', x

---------------------------


输出


$ python func_global.py

-------------------------

x is 50

Changed global x to 2

Value of x is 2

-------------------------


它如何工作


global语句被用来声明x是全局的——因此,当我们在函数内把值赋给x的时候,这个变化也反映在我们在主块中使用x的值的时候。


你可以使用同一个global语句指定多个全局变量。例如global x, y, z。


================================


7.5 使用默认参数值


对于一些函数,你可能希望它的一些参数是 可选 的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。


注意,默认参数值应该是一个参数。更加准确的说,默认参数值应该是不可变的——这会在后面的章节中做详细解释。从现在开始,请记住这一点。

--------------------------

#!/usr/bin/python

# Filename: func_default.py


def say(message, times = 1):

   print message * times


say('Hello')

say('World', 5)

---------------------------


输出


$ python func_default.py

--------------------------

Hello

WorldWorldWorldWorldWorld

--------------------------


它如何工作


名为say的函数用来打印一个字符串任意所需的次数。如果我们不提供一个值,那么默认地,字符串将只被打印一遍。我们通过给形参times指定默认参数值1来实现这一功能。


在第一次使用say的时候,我们只提供一个字符串,函数只打印一次字符串。在第二次使用say的时候,我们提供了字符串和参数5,表明我们想要 说 这个字符串消息5遍。


重要

只有在形参表末尾的那些参数可以有默认参数值,即你不能在声明函数形参的时候,先声明有默认值的形参而后声明没有默认值的形参。

这是因为赋给形参的值是根据位置而赋值的。例如,def func(a, b=5)是有效的,但是def func(a=5, b)是 无效 的。


===========================


7.6 使用关键参数

--------------------------

#!/usr/bin/python

# Filename: func_key.py


def func(a, b=5, c=10):

   print 'a is', a, 'and b is', b, 'and c is', c


func(3, 7)

func(25, c=24)

func(c=50, a=100)

-------------------------


输出


$ python func_key.py

----------------------

a is 3 and b is 7 and c is 10

a is 25 and b is 5 and c is 24

a is 100 and b is 5 and c is 50

----------------------


它如何工作


名为func的函数有一个没有默认值的参数,和两个有默认值的参数。


在第一次使用函数的时候, func(3, 7),参数a得到值3,参数b得到值7,而参数c使用默认值10。


在第二次使用函数func(25, c=24)的时候,根据实参的位置变量a得到值25。根据命名,即关键参数,参数c得到值24。变量b根据默认值,为5。


在第三次使用func(c=50, a=100)的时候,我们使用关键参数来完全指定参数值。注意,尽管函数定义中,a在c之前定义,我们仍然可以在a之前指定参数c的值。


=================================


7.7 使用字面意义上的语句


return语句用来从一个函数 返回 即跳出函数。我们也可选从函数 返回一个值 。

-----------------------------

#!/usr/bin/python

# Filename: func_return.py


def maximum(x, y):

   if x > y:

       return x

   else:

       return y


print maximum(2, 3)

------------------------------


输出


$ python func_return.py

---------

3

---------


它如何工作


maximum函数返回参数中的最大值,在这里是提供给函数的数。它使用简单的if..else语句来找出较大的值,然后 返回 那个值。


注意,没有返回值的return语句等价于return None。None是Python中表示没有任何东西的特殊类型。例如,如果一个变量的值为None,可以表示它没有值。


除非你提供你自己的return语句,每个函数都在结尾暗含有return None语句。通过运行print someFunction(),你可以明白这一点,函数someFunction没有使用return语句,如同:


def someFunction():

   pass

pass语句在Python中表示一个空的语句块。


=========================


7.8 使用DocStrings


Python有一个很奇妙的特性,称为 文档字符串 ,它通常被简称为 docstrings 。DocStrings是一个重要的工具,由于它帮助你的程序文档更加简单易懂,你应该尽量使用它。你甚至可以在程序运行的时候,从函数恢复文档字符串!


----------------------------

#!/usr/bin/python

# Filename: func_doc.py


def printMax(x, y):

   '''Prints the maximum of two numbers.


   The two values must be integers.'''

   x = int(x) # convert to integers, if possible

   y = int(y)


   if x > y:

       print x, 'is maximum'

   else:

       print y, 'is maximum'


printMax(3, 5)

print printMax.__doc__

----------------------------


输出


$ python func_doc.py

-------------------

5 is maximum

Prints the maximum of two numbers.



       The two values must be integers.

--------------------

它如何工作


在函数的第一个逻辑行的字符串是这个函数的 文档字符串 。注意,DocStrings也适用于模块和类,我们会在后面相应的章节学习它们。


文档字符串的惯例是一个多行字符串,它的首行以大写字母开始,句号结尾。第二行是空行,从第三行开始是详细的描述。 强烈建议 你在你的函数中使用文档字符串时遵循这个惯例。


你可以使用__doc__(注意双下划线)调用printMax函数的文档字符串属性(属于函数的名称)。请记住Python把 每一样东西 都作为对象,包括这个函数。我们会在后面的类一章学习更多关于对象的知识。


如果你已经在Python中使用过help(),那么你已经看到过DocStings的使用了!它所做的只是抓取函数的__doc__属性,然后整洁地展示给你。你可以对上面这个函数尝试一下——只是在你的程序中包括help(printMax)。记住按q退出help。


自动化工具也可以以同样的方式从你的程序中提取文档。因此,我 强烈建议 你对你所写的任何正式函数编写文档字符串。随你的Python发行版附带的pydoc命令,与help()类似地使用DocStrings。


===============================


8.模块


你已经学习了如何在你的程序中定义一次函数而重用代码。如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块。模块基本上就是一个包含了所有你定义的函数和变量的文件。为了在其他程序中重用模块,模块的文件名必须以.py为扩展名。


模块可以从其他程序 输入 以便利用它的功能。这也是我们使用Python标准库的方法。首先,我们将学习如何使用标准库模块。


8.1 使用sys模块

-----------------------------

#!/usr/bin/python

# Filename: using_sys.py


import sys


print 'The command line arguments are:'

for i in sys.argv:

   print i


print '\n\nThe PYTHONPATH is', sys.path, '\n'

------------------------------


输出


$ python using_sys.py we are arguments

-------------------------

The command line arguments are:

using_sys.py

we

are

arguments




The PYTHONPATH is ['/home/swaroop/byte/code', '/usr/lib/python23.zip',

'/usr/lib/python2.3', '/usr/lib/python2.3/plat-linux2',

'/usr/lib/python2.3/lib-tk', '/usr/lib/python2.3/lib-dynload',

'/usr/lib/python2.3/site-packages', '/usr/lib/python2.3/site-packages/gtk-2.0']

----------------------------

它如何工作


首先,我们利用import语句 输入 sys模块。基本上,这句语句告诉Python,我们想要使用这个模块。sys模块包含了与Python解释器和它的环境有关的函数。


当Python执行import sys语句的时候,它在sys.path变量中所列目录中寻找sys.py模块。如果找到了这个文件,这个模块的主块中的语句将被运行,然后这个模块将能够被你 使用 。注意,初始化过程仅在我们 第一次 输入模块的时候进行。另外,“sys”是“system”的缩写。


sys模块中的argv变量通过使用点号指明——sys.argv——这种方法的一个优势是这个名称不会与任何在你的程序中使用的argv变量冲突。另外,它也清晰地表明了这个名称是sys模块的一部分。


sys.argv变量是一个字符串的 列表 (列表会在后面的章节详细解释)。特别地,sys.argv包含了 命令行参数 的列表,即使用命令行传递给你的程序的参数。


如果你使用IDE编写运行这些程序,请在菜单里寻找一个指定程序的命令行参数的方法。


这里,当我们执行python using_sys.py we are arguments的时候,我们使用python命令运行using_sys.py模块,后面跟着的内容被作为参数传递给程序。Python为我们把它存储在sys.argv变量中。


记住,脚本的名称总是sys.argv列表的第一个参数。所以,在这里,'using_sys.py'是sys.argv[0]、'we'是sys.argv[1]、'are'是sys.argv[2]以及'arguments'是sys.argv[3]。注意,Python从0开始计数,而非从1开始。


sys.path包含输入模块的目录名列表。我们可以观察到sys.path的第一个字符串是空的——这个空的字符串表示当前目录也是sys.path的一部分,这与PYTHONPATH环境变量是相同的。这意味着你可以直接输入位于当前目录的模块。否则,你得把你的模块放在sys.path所列的目录之一。


=======================================


字节编译的.pyc文件


输入一个模块相对来说是一个比较费时的事情,所以Python做了一些技巧,以便使输入模块更加快一些。一种方法是创建 字节编译的文件 ,这些文件以.pyc作为扩展名。字节编译的文件与Python变换程序的中间状态有关(是否还记得Python如何工作的介绍?)。当你在下次从别的程序输入这个模块的时候,.pyc文件是十分有用的——它会快得多,因为一部分输入模块所需的处理已经完成了。另外,这些字节编译的文件也是与平台无关的。所以,现在你知道了那些.pyc文件事实上是什么了。


==========================================


from..import语句


如果你想要直接输入argv变量到你的程序中(避免在每次使用它时打sys.),那么你可以使用from sys import argv语句。如果你想要输入所有sys模块使用的名字,那么你可以使用from sys import *语句。这对于所有模块都适用。一般说来,应该避免使用from..import而使用import语句,因为这样可以使你的程序更加易读,也可以避免名称的冲突。


=======================================


8.2 使用模块的__name__


每个模块都有一个名称,在模块中可以通过语句来找出模块的名称。这在一个场合特别有用——就如前面所提到的,当一个模块被第一次输入的时候,这个模块的主块将被运行。假如我们只想在程序本身被使用的时候运行主块,而在它被别的模块输入的时候不运行主块,我们该怎么做呢?这可以通过模块的__name__属性完成。


--------------------------------

#!/usr/bin/python

# Filename: using_name.py


if __name__ == '__main__':

   print 'This program is being run by itself'

else:

   print 'I am being imported from another module'

--------------------------------


输出


$ python using_name.py

---------------------------

This program is being run by itself

---------------------------


$ python

>>> import using_name

I am being imported from another module

>>>


它如何工作


每个Python模块都有它的__name__,如果它是'__main__',这说明这个模块被用户单独运行,我们可以进行相应的恰当操作。


=============================


8.3 如何创建你自己的模块


创建你自己的模块是十分简单的,你一直在这样做!每个Python程序也是一个模块。你已经确保它具有.py扩展名了。下面这个例子将会使它更加清晰。

-------------------------------

#!/usr/bin/python

# Filename: mymodule.py


def sayhi():

   print 'Hi, this is mymodule speaking.'


version = '0.1'


# End of mymodule.py

---------------------------------


上面是一个 模块 的例子。你已经看到,它与我们普通的Python程序相比并没有什么特别之处。我们接下来将看看如何在我们别的Python程序中使用这个模块。


记住这个模块应该被放置在我们输入它的程序的同一个目录中,或者在sys.path所列目录之一。

---------------------------------

#!/usr/bin/python

# Filename: mymodule_demo.py


import mymodule


mymodule.sayhi()

print 'Version', mymodule.version

------------------------------


输出


$ python mymodule_demo.py

Hi, this is mymodule speaking.

Version 0.1

它如何工作


注意我们使用了相同的点号来使用模块的成员。Python很好地重用了相同的记号来,使我们这些Python程序员不需要不断地学习新的方法。


from..import


下面是一个使用from..import语法的版本。

-------------------------------------

#!/usr/bin/python

# Filename: mymodule_demo2.py


from mymodule import sayhi, version

# Alternative:

# from mymodule import *


sayhi()

print 'Version', version

-----------------------------------


mymodule_demo2.py的输出与mymodule_demo.py完全相同。



================================


8.4 使用dir函数


你可以使用内建的dir函数来列出模块定义的标识符。标识符有函数、类和变量。


当你为dir()提供一个模块名的时候,它返回模块定义的名称列表。如果不提供参数,它返回当前模块中定义的名称列表。


$ python

>>> import sys

>>> dir(sys) # get list of attributes for sys module

['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',

'__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',

'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',

'copyright', 'displayhook', 'exc_clear', 'exc_info', 'exc_type',

'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval',

'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding',

'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',

'meta_path','modules', 'path', 'path_hooks', 'path_importer_cache',

'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',

'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',

'version', 'version_info', 'warnoptions']

>>> dir() # get list of attributes for current module

['__builtins__', '__doc__', '__name__', 'sys']

>>>

>>> a = 5 # create a new variable 'a'

>>> dir()

['__builtins__', '__doc__', '__name__', 'a', 'sys']

>>>

>>> del a # delete/remove a name

>>>

>>> dir()

['__builtins__', '__doc__', '__name__', 'sys']

>>>

它如何工作


首先,我们来看一下在输入的sys模块上使用dir。我们看到它包含一个庞大的属性列表。


接下来,我们不给dir函数传递参数而使用它——默认地,它返回当前模块的属性列表。注意,输入的模块同样是列表的一部分。


为了观察dir的作用,我们定义一个新的变量a并且给它赋一个值,然后检验dir,我们观察到在列表中增加了以上相同的值。我们使用del语句删除当前模块中的变量/属性,这个变化再一次反映在dir的输出中。


关于del的一点注释——这个语句在运行后被用来 删除 一个变量/名称。在这个例子中,del a,你将无法再使用变量a——它就好像从来没有存在过一样。


==============================


概括


模块的用处在于它能为你在别的程序中重用它提供的服务和功能。Python附带的标准库就是这样一组模块的例子。我们已经学习了如何使用这些模块以及如何创造我们自己的模块。


接下来,我们将学习一些有趣的概念,它们称为数据结构。


==============================


9. 数据结构


数据结构基本上就是——它们是可以处理一些 数据 的 结构 。或者说,它们是用来存储一组相关数据的。


在Python中有三种内建的数据结构——列表、元组和字典。我们将会学习如何使用它们,以及它们如何使编程变得简单。


9.1 使用列表


list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个 序列 的项目。假想你有一个购物列表,上面记载着你要买的东西,你就容易理解列表了。只不过在你的购物表上,可能每样东西都独自占有一行,而在Python中,你在每个项目之间用逗号分割。


列表中的项目应该包括在方括号中,这样Python就知道你是在指明一个列表。一旦你创建了一个列表,你可以添加、删除或是搜索列表中的项目。由于你可以增加或删除项目,我们说列表是 可变的 数据类型,即这种类型是可以被改变的。


对象与类的快速入门


尽管我一直推迟讨论对象和类,但是现在对它们做一点解释可以使你更好的理解列表。我们会在相应的章节详细探索这个主题。


列表是使用对象和类的一个例子。当你使用变量i并给它赋值的时候,比如赋整数5,你可以认为你创建了一个类(类型)int的对象(实例)i。事实上,你可以看一下help(int)以更好地理解这一点。


类也有方法,即仅仅为类而定义地函数。仅仅在你有一个该类的对象的时候,你才可以使用这些功能。例如,Python为list类提供了append方法,这个方法让你在列表尾添加一个项目。例如mylist.append('an item')列表mylist中增加那个字符串。注意,使用点号来使用对象的方法。


一个类也有域,它是仅仅为类而定义的变量。仅仅在你有一个该类的对象的时候,你才可以使用这些变量/名称。类也通过点号使用,例如mylist.field。


-----------------------------

#!/usr/bin/python

# Filename: using_list.py


# This is my shopping list

shoplist = ['apple', 'mango', 'carrot', 'banana']


print 'I have', len(shoplist),'items to purchase.'


print 'These items are:', # Notice the comma at end of the line

for item in shoplist:

   print item,


print '\nI also have to buy rice.'

shoplist.append('rice')

print 'My shopping list is now', shoplist


print 'I will sort my list now'

shoplist.sort()

print 'Sorted shopping list is', shoplist


print 'The first item I will buy is', shoplist[0]

olditem = shoplist[0]

del shoplist[0]

print 'I bought the', olditem

print 'My shopping list is now', shoplist

-------------------------------


输出


$ python using_list.py

--------------------

I have 4 items to purchase.

These items are: apple mango carrot banana

I also have to buy rice.

My shopping list is now ['apple', 'mango', 'carrot', 'banana', 'rice']

I will sort my list now

Sorted shopping list is ['apple', 'banana', 'carrot', 'mango', 'rice']

The first item I will buy is apple

I bought the apple

My shopping list is now ['banana', 'carrot', 'mango', 'rice']

------------------------


它如何工作


变量shoplist是某人的购物列表。在shoplist中,我们只存储购买的东西的名字字符串,但是记住,你可以在列表中添加 任何种类的对象 包括数甚至其他列表。


我们也使用了for..in循环在列表中各项目间递归。从现在开始,你一定已经意识到列表也是一个序列。序列的特性会在后面的章节中讨论。


注意,我们在print语句的结尾使用了一个 逗号 来消除每个print语句自动打印的换行符。这样做有点难看,不过确实简单有效。


接下来,我们使用append方法在列表中添加了一个项目,就如前面已经讨论过的一样。然后我们通过打印列表的内容来检验这个项目是否确实被添加进列表了。打印列表只需简单地把列表传递给print语句,我们可以得到一个整洁的输出。


再接下来,我们使用列表的sort方法来对列表排序。需要理解的是,这个方法影响列表本身,而不是返回一个修改后的列表——这与字符串工作的方法不同。这就是我们所说的列表是 可变的 而字符串是 不可变的 。


最后,但我们完成了在市场购买一样东西的时候,我们想要把它从列表中删除。我们使用del语句来完成这个工作。这里,我们指出我们想要删除列表中的哪个项目,而del语句为我们从列表中删除它。我们指明我们想要删除列表中的第一个元素,因此我们使用del shoplist[0](记住,Python从0开始计数)。


如果你想要知道列表对象定义的所有方法,可以通过help(list)获得完整的知识。



======================================


9.2 使用元组


元组和列表十分类似,只不过元组和字符串一样是 不可变的 即你不能修改元组。元组通过圆括号中用逗号分割的项目定义。元组通常用在使语句或用户定义的函数能够安全地采用一组值的时候,即被使用的元组的值不会改变。


---------------------------------

#!/usr/bin/python

# Filename: using_tuple.py


zoo = ('wolf', 'elephant', 'penguin')

print 'Number of animals in the zoo is', len(zoo)


new_zoo = ('monkey', 'dolphin', zoo)

print 'Number of animals in the new zoo is', len(new_zoo)

print 'All animals in new zoo are', new_zoo

print 'Animals brought from old zoo are', new_zoo[2]

print 'Last animal brought from old zoo is', new_zoo[2][2]

---------------------------------


输出


$ python using_tuple.py

---------------------------

Number of animals in the zoo is 3

Number of animals in the new zoo is 3

All animals in new zoo are ('monkey', 'dolphin', ('wolf', 'elephant', 'penguin'))

Animals brought from old zoo are ('wolf', 'elephant', 'penguin')

Last animal brought from old zoo is penguin

-----------------------------


它如何工作


变量zoo是一个元组,我们看到len函数可以用来获取元组的长度。这也表明元组也是一个序列。


由于老动物园关闭了,我们把动物转移到新动物园。因此,new_zoo元组包含了一些已经在那里的动物和从老动物园带过来的动物。回到话题,注意元组之内的元组不会失去它的身份。


我们可以通过一对方括号来指明某个项目的位置从而来访问元组中的项目,就像我们对列表的用法一样。这被称作 索引 运算符。我们使用new_zoo[2]来访问new_zoo中的第三个项目。我们使用new_zoo[2][2]来访问new_zoo元组的第三个项目的第三个项目。


含有0个或1个项目的元组。一个空的元组由一对空的圆括号组成,如myempty = ()。然而,含有单个元素的元组就不那么简单了。你必须在第一个(唯一一个)项目后跟一个逗号,这样Python才能区分元组和表达式中一个带圆括号的对象。即如果你想要的是一个包含项目2的元组的时候,你应该指明singleton = (2 , )。


给Perl程序员的注释

列表之中的列表不会失去它的身份,即列表不会像Perl中那样被打散。同样元组中的元组,或列表中的元组,或元组中的列表等等都是如此。只要是Python,它们就只是使用另一个对象存储的对象。

元组与打印语句


元组最通常的用法是用在打印语句中,下面是一个例子:


9.3 使用元组输出

-----------------------

#!/usr/bin/python

# Filename: print_tuple.py


age = 22

name = 'Swaroop'


print '%s is %d years old' % (name, age)

print 'Why is %s playing with that python?' % name

------------------------


输出


$ python print_tuple.py

--------------------

Swaroop is 22 years old

Why is Swaroop playing with that python?

--------------------


它如何工作


print语句可以使用跟着%符号的项目元组的字符串。这些字符串具备定制的功能。定制让输出满足某种特定的格式。定制可以是%s表示字符串或%d表示整数。元组必须按照相同的顺序来对应这些定制。


观察我们使用的第一个元组,我们首先使用%s,这对应变量name,它是元组中的第一个项目。而第二个定制是%d,它对应元组的第二个项目age。


Python在这里所做的是把元组中的每个项目转换成字符串并且用字符串的值替换定制的位置。因此%s被替换为变量name的值,依此类推。


print的这个用法使得编写输出变得极其简单,它避免了许多字符串操作。它也避免了我们一直以来使用的逗号。


在大多数时候,你可以只使用%s定制,而让Python来提你处理剩余的事情。这种方法对数同样奏效。然而,你可能希望使用正确的定制,从而可以避免多一层的检验程序是否正确。


在第二个print语句中,我们使用了一个定制,后面跟着%符号后的单个项目——没有圆括号。这只在字符串中只有一个定制的时候有效。


===============================


9.4 使用字典


字典类似于你通过联系人名字查找地址和联系人详细情况的地址簿,即,我们把键(名字)和值(详细情况)联系在一起。注意,键必须是唯一的,就像如果有两个人恰巧同名的话,你无法找到正确的信息。


注意,你只能使用不可变的对象(比如字符串)来作为字典的键,但是你可以不可变或可变的对象作为字典的值。基本说来就是,你应该只使用简单的对象作为键。


键值对在字典中以这样的方式标记:d = {key1 : value1, key2 : value2 }。注意它们的键/值对用冒号分割,而各个对用逗号分割,所有这些都包括在花括号中。


记住字典中的键/值对是没有顺序的。如果你想要一个特定的顺序,那么你应该在使用前自己对它们排序。


字典是dict类的实例/对象。


---------------------------

#!/usr/bin/python

# Filename: using_dict.py


# 'ab' is short for 'a'ddress'b'ook


ab = {       'Swaroop'   : 'swaroopch@byteofpython.info',

            'Larry'     : 'larry@wall.org',

            'Matsumoto' : 'matz@ruby-lang.org',

            'Spammer'   : 'spammer@hotmail.com'

    }


print "Swaroop's address is %s" % ab['Swaroop']


# Adding a key/value pair

ab['Guido'] = 'guido@python.org'


# Deleting a key/value pair

del ab['Spammer']


print '\nThere are %d contacts in the address-book\n' % len(ab)

for name, address in ab.items():

   print 'Contact %s at %s' % (name, address)


if 'Guido' in ab: # OR ab.has_key('Guido')

   print "\nGuido's address is %s" % ab['Guido']

-------------------------------


输出


$ python using_dict.py

--------------------------

Swaroop's address is swaroopch@byteofpython.info


There are 4 contacts in the address-book


Contact Swaroop at swaroopch@byteofpython.info

Contact Matsumoto at matz@ruby-lang.org

Contact Larry at larry@wall.org

Contact Guido at guido@python.org


Guido's address is guido@python.org

-----------------------


它如何工作


我们使用已经介绍过的标记创建了字典ab。然后我们使用在列表和元组章节中已经讨论过的索引操作符来指定键,从而使用键/值对。我们可以看到字典的语法同样十分简单。


我们可以使用索引操作符来寻址一个键并为它赋值,这样就增加了一个新的键/值对,就像在上面的例子中我们对Guido所做的一样。


我们可以使用我们的老朋友——del语句来删除键/值对。我们只需要指明字典和用索引操作符指明要删除的键,然后把它们传递给del语句就可以了。执行这个操作的时候,我们无需知道那个键所对应的值。


接下来,我们使用字典的items方法,来使用字典中的每个键/值对。这会返回一个元组的列表,其中每个元组都包含一对项目——键与对应的值。我们抓取这个对,然后分别赋给for..in循环中的变量name和address然后在for-块中打印这些值。


我们可以使用in操作符来检验一个键/值对是否存在,或者使用dict类的has_key方法。你可以使用help(dict)来查看dict类的完整方法列表。


关键字参数与字典。如果换一个角度看待你在函数中使用的关键字参数的话,你已经使用了字典了!只需想一下——你在函数定义的参数列表中使用的键/值对。当你在函数中使用变量的时候,它只不过是使用一个字典的键(这在编译器设计的术语中被称作 符号表 )。


==============================


9.5 使用序列


列表、元组和字符串都是序列,但是序列是什么,它们为什么如此特别呢?序列的两个主要特点是索引操作符和切片操作符。索引操作符让我们可以从序列中抓取一个特定项目。切片操作符让我们能够获取序列的一个切片,即一部分序列。

------------------------

#!/usr/bin/python

# Filename: seq.py


shoplist = ['apple', 'mango', 'carrot', 'banana']


# Indexing or 'Subscription' operation

print 'Item 0 is', shoplist[0]

print 'Item 1 is', shoplist[1]

print 'Item 2 is', shoplist[2]

print 'Item 3 is', shoplist[3]

print 'Item -1 is', shoplist[-1]

print 'Item -2 is', shoplist[-2]


# Slicing on a list

print 'Item 1 to 3 is', shoplist[1:3]

print 'Item 2 to end is', shoplist[2:]

print 'Item 1 to -1 is', shoplist[1:-1]

print 'Item start to end is', shoplist[:]


# Slicing on a string

name = 'swaroop'

print 'characters 1 to 3 is', name[1:3]

print 'characters 2 to end is', name[2:]

print 'characters 1 to -1 is', name[1:-1]

print 'characters start to end is', name[:]

------------------------


输出


$ python seq.py

--------------------------

Item 0 is apple

Item 1 is mango

Item 2 is carrot

Item 3 is banana

Item -1 is banana

Item -2 is carrot

Item 1 to 3 is ['mango', 'carrot']

Item 2 to end is ['carrot', 'banana']

Item 1 to -1 is ['mango', 'carrot']

Item start to end is ['apple', 'mango', 'carrot', 'banana']

characters 1 to 3 is wa

characters 2 to end is aroop

characters 1 to -1 is waroo

characters start to end is swaroop

-------------------------


它如何工作


首先,我们来学习如何使用索引来取得序列中的单个项目。这也被称作是下标操作。每当你用方括号中的一个数来指定一个序列的时候,Python会为你抓取序列中对应位置的项目。记住,Python从0开始计数。因此,shoplist[0]抓取第一个项目,shoplist[3]抓取shoplist序列中的第四个元素。


索引同样可以是负数,在那样的情况下,位置是从序列尾开始计算的。因此,shoplist[-1]表示序列的最后一个元素而shoplist[-2]抓取序列的倒数第二个项目。


切片操作符是序列名后跟一个方括号,方括号中有一对可选的数字,并用冒号分割。注意这与你使用的索引操作符十分相似。记住数是可选的,而冒号是必须的。


切片操作符中的第一个数(冒号之前)表示切片开始的位置,第二个数(冒号之后)表示切片到哪里结束。如果不指定第一个数,Python就从序列首开始。如果没有指定第二个数,则Python会停止在序列尾。注意,返回的序列从开始位置 开始 ,刚好在 结束 位置之前结束。即开始位置是包含在序列切片中的,而结束位置被排斥在切片外。


这样,shoplist[1:3]返回从位置1开始,包括位置2,但是停止在位置3的一个序列切片,因此返回一个含有两个项目的切片。类似地,shoplist[:]返回整个序列的拷贝。


你可以用负数做切片。负数用在从序列尾开始计算的位置。例如,shoplist[:-1]会返回除了最后一个项目外包含所有项目的序列切片。


使用Python解释器交互地尝试不同切片指定组合,即在提示符下你能够马上看到结果。序列的神奇之处在于你可以用相同的方法访问元组、列表和字符串。


============================


9.6 对象与参考


当你创建一个对象并给它赋一个变量的时候,这个变量仅仅 参考 那个对象,而不是表示这个对象本身!也就是说,变量名指向你计算机中存储那个对象的内存。这被称作名称到对象的绑定。


一般说来,你不需要担心这个,只是在参考上有些细微的效果需要你注意。这会通过下面这个例子加以说明。

----------------------------

#!/usr/bin/python

# Filename: reference.py


print 'Simple Assignment'

shoplist = ['apple', 'mango', 'carrot', 'banana']

mylist = shoplist # mylist is just another name pointing to the same object!


del shoplist[0]


print 'shoplist is', shoplist

print 'mylist is', mylist

# notice that both shoplist and mylist both print the same list without

# the 'apple' confirming that they point to the same object


print 'Copy by making a full slice'

mylist = shoplist[:] # make a copy by doing a full slice

del mylist[0] # remove first item


print 'shoplist is', shoplist

print 'mylist is', mylist

# notice that now the two lists are different

------------------------------


输出


$ python reference.py

--------------------------

Simple Assignment

shoplist is ['mango', 'carrot', 'banana']

mylist is ['mango', 'carrot', 'banana']

Copy by making a full slice

shoplist is ['mango', 'carrot', 'banana']

mylist is ['carrot', 'banana']

----------------------------


它如何工作


大多数解释已经在程序的注释中了。你需要记住的只是如果你想要复制一个列表或者类似的序列或者其他复杂的对象(不是如整数那样的简单 对象 ),那么你必须使用切片操作符来取得拷贝。如果你只是想要使用另一个变量名,两个名称都 参考 同一个对象,那么如果你不小心的话,可能会引来各种麻烦。


给Perl程序员的注释

记住列表的赋值语句不创建拷贝。你得使用切片操作符来建立序列的拷贝。


============================


9.7 字符串的方法


我们已经在前面详细讨论了字符串。我们还需要知道什么呢?那么,你是否知道字符串也是对象,同样具有方法。这些方法可以完成包括检验一部分字符串和去除空格在内的各种工作。


你在程序中使用的字符串都是str类的对象。这个类的一些有用的方法会在下面这个例子中说明。如果要了解这些方法的完整列表,请参见help(str)。

--------------------------------

#!/usr/bin/python

# Filename: str_methods.py


name = 'Swaroop' # This is a string object


if name.startswith('Swa'):

   print 'Yes, the string starts with "Swa"'


if 'a' in name:

   print 'Yes, it contains the string "a"'


if name.find('war') != -1:

   print 'Yes, it contains the string "war"'


delimiter = '_*_'

mylist = ['Brazil', 'Russia', 'India', 'China']

print delimiter.join(mylist)

-----------------------------------


输出


$ python str_methods.py

---------------------------

Yes, the string starts with "Swa"

Yes, it contains the string "a"

Yes, it contains the string "war"

Brazil_*_Russia_*_India_*_China

------------------------------


它如何工作


这里,我们看到使用了许多字符串方法。startwith方法是用来测试字符串是否以给定字符串开始。in操作符用来检验一个给定字符串是否为另一个字符串的一部分。


find方法用来找出给定字符串在另一个字符串中的位置,或者返回-1以表示找不到子字符串。str类也有以一个作为分隔符的字符串join序列的项目的整洁的方法,它返回一个生成的大字符串。


==================================


概括


我们已经详细探讨了多种Python内建的数据结构。这些数据结构将是编写程序时至关重要的部分。


现在我们已经掌握了很多Python的基本知识,我们接下来将学习如何设计和编写一个实用的Python程序。