# Python 學習筆記 基礎篇
整理:Jims of [肥肥世家](http://www.ringkee.com)
[jims.yang@gmail.com](mailto:jims.yang@gmail.com)
Copyright ? 2004,2005,2006 本文遵從GNU 的自由文檔許可證(Free Document License)的條款,歡迎轉載、修改、散布。
發布時間:2004年07月10日
更新時間:2006年06月14日,把參考篇的內容合并進來。
**Abstract**
現時國內python的中文資料極少,使學習Python較困難。國外的資料雖多,但都是英文的,使我們學習起來很不方便。有鑒于此,我開始了Python中文資料庫的整理工作,以推動Python的發展和在中國的應用。在自由的世界里,正因為有你的支持和幫助,才使我得以不斷前進。我相信我們每人一小步就可帶動python在中國前進一大步。
<!--more-->
**Table of Contents**
+ [1\. 緒論](#id2875104)
+ [1.1\. Python歷史](#id2811704)
+ [1.2\. Python功能簡介](#id2811781)
+ [1.3\. 應用范圍](#id2810170)
+ [1.4\. 如何開始?](#id2810267)
+ [2\. Python編程習慣與特點](#id2861425)
+ [2.1\. 代碼風格](#id2861433)
+ [2.2\. 保留字](#id2861575)
+ [2.3\. Python運算符和表達式](#id2861594)
+ [2.3.1\. Python運算符](#id2861602)
+ [2.3.2\. 運算符優先順序](#id2861844)
+ [2.3.3\. 真值表](#id2808594)
+ [2.3.4\. 復合表達式](#id2808746)
+ [2.4\. 給變量賦值](#id2808820)
+ [3\. Python內建對象類型](#id2808911)
+ [3.1\. Number數值型](#id2808928)
+ [3.2\. String字符串型](#id2809008)
+ [3.2.1\. 字符串的格式化](#id2809192)
+ [3.2.2\. 轉義字符](#id2809469)
+ [3.2.3\. Unicode字符串](#id2875369)
+ [3.2.4\. 原始字符串](#id2875512)
+ [3.3\. List列表](#id2875536)
+ [3.4\. Tuple元組](#id2875904)
+ [3.5\. 序列對象](#id2875979)
+ [3.6\. Dictionary字典](#id2876078)
+ [3.7\. File文件](#id2876321)
+ [3.8\. 理解引用](#id2876343)
+ [3.9\. copy and deepcopy](#id2876409)
+ [3.10\. 標識數據類型](#id2876486)
+ [3.11\. 數組對象](#id2876523)
+ [4\. 控制語句](#id2876868)
+ [5\. 函數](#id2877126)
+ [5.1\. 常用函數](#id2877464)
+ [5.2\. 內置類型轉換函數](#id2877751)
+ [5.3\. 序列處理函數](#id2878060)
+ [6\. 模塊](#id2878241)
+ [6.1\. String模塊](#id2878430)
+ [6.2\. time模塊](#id2878537)
+ [7\. 類](#id2878619)
+ [8\. 異常處理](#id2878694)
+ [9\. 文件處理](#id2878856)
+ [9.1\. 文件處理的函數和方法](#id2878871)
+ [9.2\. 示例](#id2879330)
+ [10\. 正則表達式](#id2879657)
+ [10.1\. 基本元素](#id2879700)
+ [10.2\. 操作](#id2880568)
+ [11\. 調試](#id2881059)
+ [12\. HOW-TO](#id2881117)
## Chapter 1\. 緒論
## 1.1\. Python歷史
Python是一種開源的面向對象的腳本語言,它起源于1989年末,當時,CWI(阿姆斯特丹國家數學和計算機科學研究所)的研究員Guido van Rossum需要一種高級腳本編程語言,為其研究小組的Amoeba分布式操作系統執行管理任務。為創建新語言,他從高級數學語言ABC(ALL BASIC CODE)汲取了大量語法,并從系統編程語言Modula-3借鑒了錯語處理機制。Van Rossum把這種新的語言命名為Python(大蟒蛇)---來源于BBC當時正在熱播的喜劇連續劇“Monty Python”。
Python于1991年初公開發行,由于功能強大和采用開源方式發行,Python的發展得很快,用戶越來越多,形成了一個強大的社區力量。2001年,Python的核心開發團隊移師Digital Creations公司,該公司是Zope(一個用Python編寫的web應用服務器)的創始者。現在最新的版本是python2.3.4,大家可到[http://www.python.org](http://www.python.org)上了解最新的Python動態和資料 。
## 1.2\. Python功能簡介
Python是一種解析性的,交互式的,面向對象的編程語言,類似于Perl、Tcl、Scheme或Java。
Python一些主要功能介紹:
* Python使用一種優雅的語法,可讀性強。
* Python是一種很靈活的語言,能幫你輕松完成編程工作。并可作為一種原型開發語言,加快大型程序的開發速度。
* 有多種數據類型:numbers (integers, floating point, complex, and unlimited-length long integers), strings (ASCII 和 Unicode), lists, dictionaries。
* Python支持類和多層繼承等的面向對象編程技術。
* 代碼能打包成模塊和包,方便管理和發布。
* 支持異常處理,能有效捕獲和處理程序中發生的錯誤。
* 強大的動態數據類型支持,不同數據類型相加會引發一個異常。
* Python支持如生成器和列表嵌套等高級編程功能。
* 自動內存碎片管理,有效利用內存資源。
* 強大的類庫支持,使編寫文件處理、正則表達式,網絡連接等程序變得相當容易。
* Python的交互命令行模塊能方便地進行小代碼調試和學習。
* Python易于擴展,可以通過C或C++編寫的模塊進行功能擴展。
* Python解析器可作為一個編程接口嵌入一個應用程序中。
* Python可運行在多種計算機平臺和操作系統中,如各位unix,windows,MacOS,OS/2等等。
* Python是開源的,可自由免費使用和發布,并且可用于商業用途以獲取利潤。如想詳細了解Python的許可協議可到以下網址查詢[http://www.python.org/psf/license.html](http://www.python.org/psf/license.html)
## 1.3\. 應用范圍
* 系統編程,提供大量系統接口API,能方便進行系統維護和管理。
* 圖形處理,有PIL、Tkinter等圖形庫支持,能方便進行圖形處理。
* 數學處理,NumPy擴展提供大量與許多標準數學庫的接口,
* 文本處理,python提供的re模塊能支持正則表達式,還提供SGML,XML分析模塊,許多程序員利用python進行XML程序的開發。
* 數據庫編程,程序員可通過遵循Python DB-API(數據庫應用程序編程接口)規范的模塊與Microsoft SQL Server,Oracle,Sybase,DB2,Mysql等數據庫通信。python自帶有一個Gadfly模塊,提供了一個完整的SQL環境。
* 網絡編程,提供豐富的模塊支持sockets編程,能方便快速地開發分布式應用程序。
* 作為Web應用的開發語言,支持最新的XML技術。
* 多媒體應用,Python的PyOpenGL模塊封裝了“OpenGL應用程序編程接口”,能進行二維和三維圖像處理。PyGame模塊可用于編寫游戲軟件。
## 1.4\. 如何開始?
* 進入交互命令行方式。如果是linux類的系統,python解析器應該已經安裝在/usr/local/bin/python中,直接打python就可進入交互式命令行界面,如下所示:
```
Python 2.3.3 (#1, Apr 27 2004, 15:17:58)
[GCC 3.2 20020903 (Red Hat Linux 8.0 3.2-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
“>>>”符號是Python命令行界面的提示符,可按CTRL+D退出,如果是windows環境的話就要按CTRL+Z了。還可以用以下命令退出命令行界面:“import sys;sys.exit()”。如果是windows系統,可到[http://www.python.org/download/](http://www.python.org/download/)下載最新的安裝程序進行安裝。安裝完成后直接打python也可進入命令行界面。命令行是python最簡單直觀,也是最方便的一種執行環境,我們可以在這里學習python語法和調試程序。如果要打印"hello world"可以輸入以下命令:
```
>>>print "hello world"
hello world
```
* 以模塊文件方式運行。模塊文件是包含python語句的文本,以.py結尾。運行模塊文件只要輸入python xxx.py就可以了。
* 以linux腳本方式運行。和shell腳本差不多,以vi或其它文本編輯器輸入以下內容:
```
#!/usr/local/bin/python
print "test ............"
```
存盤后,把文件屬性改為可執行,就可象shell腳本一樣執行了。
* **Table 1.1\. Python命令行選項**
```
| 選項 | 作用 |
| --- | --- |
| -c cmd | 在命令行直接執行python代碼。如python -c 'print "hello world"'。 |
| -d | 腳本編譯后從解釋器產生調試信息。同PYTHONDEBUG=1。 |
| -E | 忽略環境變量。 |
| -h | 顯示python命令行選項幫助信息。 |
| -i | 腳本執行后馬上進入交互命令行模式。同PYTHONINSPECT=1。 |
| -O | 在執行前對解釋器產生的字節碼進行優化。同 PYTHONOPTIMIZE=1。 |
| -OO | 在執行前對解釋器產生的字節碼進行優化,并刪除優化代碼中的嵌入式文檔字符串。 |
| -Q arg | 除法規則選項,-Qold(default),-Qwarn,-Qwarnall,-Qnew。 |
| -S | 解釋器不自動導入site.py模塊。 |
| -t | 當腳本的tab縮排格式不一致時產生警告。 |
| -u | 不緩沖stdin、stdout和stderr,默認是緩沖的。同PYTHONUNBUFFERED=1。 |
| -v | 產生每個模塊的信息。如果兩個-v選項,則產生更詳細的信息。同PYTHONVERBOSE=x。 |
| -V | 顯示Python的版本信息。 |
| -W arg | 出錯信息控制。(arg is action:message:category:module:lineno) |
| -x | 忽略源文件的首行。要在多平臺上執行腳本時有用。 |
| file | 執行file里的代碼。 |
| - | 從stdin里讀取執行代碼。 |
```
## Chapter 2\. Python編程習慣與特點
## 2.1\. 代碼風格
* 在Python中,每行程序以換行符代表結束,如果一行程序太長的話,可以用“\”符號擴展到下一行。在python中以三引號(""")括起來的字符串,列表,元組和字典都能跨行使用。并且以小括號(...)、中括號[...]和大括號{...}包圍的代碼不用加“\”符也可擴展到多行。如:
* 在Python中是以縮進來區分程序功能塊的,縮進的長度不受限制,但就一個功能塊來講,最好保持一致的縮進量。
* 如果一行中有多條語句,語句間要以分號(;)分隔。
* 以“#”號開頭的內容為注釋,python解釋器會忽略該行內容。
* 在python中,所有標識符可以包括英文、數字以及下劃線(\_),但不能以數字開頭。python中的標識符是區分大小寫的。
* 以下劃線開頭的標識符是有特殊意義的。以單下劃線開頭(\_foo)的代表不能直接訪問的類屬性,需通過類提供的接口進行訪問,不能用“from xxx import \*”而導入;以雙下劃線開頭的(\_\_foo)代表類的私有成員;以雙下劃線開頭和結尾的(\_\_foo\_\_)代表python里特殊方法專用的標識,如\_\_init\_\_()代表類的構造函數。
* 在交互模式下運行python時,一個下劃線字符(\_)是特殊標識符,它保留了表達式的最后一個計算結果。
```
>>> "hello"
'hello'
>>> _
'hello'
>>> 10+10
20
>>> _
20
```
* 在python中,函數、類、模塊定義的第一段代碼如果是字符串的話,就把它叫作文件字串,可通過\_\_doc\_\_屬性訪問。如:
```
def test():
"this is a document string"
return 100+1000
>>>print test.__doc__
this is a document string
```
## 2.2\. 保留字
```
and elif global or yield
assert else if pass
break except import print
class exec in raise
continue finally is return
def for lambda try
del from not while
```
## 2.3\. Python運算符和表達式
### 2.3.1\. Python運算符
**Table 2.1\. Python運算符列表**
| 運算符 | 描述 |
| --- | --- |
| x+y,x-y | 加、減,“+”號可重載為連接符 |
| x\*y,x\*\*y,x/y,x%y | 相乘、求平方、相除、求余,“*”號可重載為重復,“%”號可重載為格式化 |
| <,<=,>,>=,==,<>,!= | 比較運算符 |
| +=,-=,\*=,/=,%=,\*\*=,<<=,>>=,&=,^=,|= | 自變運算符 |
| x|y | 按位或 |
| x^y | 按位異或 |
| x&y | 按位與 |
| ~x | 按位取反 |
| x<<,x>>y | x向左或向右移y位 |
| is, is not | 等同測試 |
| in, not in | 是否為成員測試 |
| or,and,not | 邏輯運算符 |
| x[i],x[i:j],x.y,x(...) | 索引,分片,限定引用,函數調用 |
| (...),[...],{...},'...' | 元組,列表,字典,轉化為字符串 |
### 2.3.2\. 運算符優先順序
**Table 2.2\. 運算符優先順序列表(從最高到最低)**
| 運算符 | 描述 |
| --- | --- |
| 'expr' | 字符串轉換 |
| {key:expr,...} | 字典 |
| [expr1,expr2...] | 列表 |
| (expr1,expr2,...) | 元組 |
| function(expr,...) | 函數調用 |
| x[index:index] | 切片 |
| x[index] | 下標索引取值 |
| x.attribute | 屬性引用 |
| ~x | 按位取反 |
| +x,-x | 正,負 |
| x\*\*y | 冪 |
| x\*y,x/y,x%y | 乘,除,取模 |
| x+y,x-y | 加,減 |
| x<<y,x>>y | 移位 |
| x&y | 按位與 |
| x^y | 按位異或 |
| x|y | 按位或 |
| x<y,x<=y,x==y,x!=y,x>=y,x>y | 比較 |
| x is y,x is not y | 等同測試 |
| x in y,x not in y | 成員判斷 |
| not x | 邏輯否 |
| x and y | 邏輯與 |
| x or y | 邏輯或 |
| lambda arg,...:expr | Lambda匿名函數 |
### 2.3.3\. 真值表
**Table 2.3\.**
| 對象/常量 | 值 |
| --- | --- |
| "" | 假 |
| "string" | 真 |
| 0 | 假 |
| >=1 | 真 |
| <=-1 | 真 |
| ()空元組 | 假 |
| []空列表 | 假 |
| {}空字典 | 假 |
| None | 假 |
### 2.3.4\. 復合表達式
* 對于and,當計算a and b時,python會計算a,如果a為假,則取a值,如果a為真,則python會計算b且整個表達式會取b值。如:
```
>>> a,b=10,20
>>> a and b #a is true
20
>>> a,b=0,5 #a is false
>>> a and b
0
```
* 對于or,當計算a or b時,python會計算a,如果a為真,則整個表達式取a值,如果a為假,表達式將取b值。如:
```
>>> a,b=10,20
>>> a or b
10
>>> a,b=0,5
>>> a or b
5
```
* 對于not,not將反轉表表達式的“實際值”,如果表達式為真,not為返回假,如為表達式為假,not為返回真。如:
```
>>> not 2
False
>>> not 0
True
>>> not "test"
False
>>> not ""
True
```
## 2.4\. 給變量賦值
* 簡單賦值,Variable(變量)=Value(值)。
```
>>>a=1
>>>b=2
>>>print a,b
1 2
```
* 多變量賦值,Variable1,variable2,...=Value1,Value2,...
```
>>>a,b,c=1,2,3
>>>print a
1
>>>print b
2
>>>print c
3
```
多變量賦值也可用于變量交換,接上例:
```
>>>a,b,c=c,b,a
>>>print a
3
>>>print b
2
>>>print c
1
```
* 多目標賦值,a=b=variable
```
>>> a=b=1
>>> a
1
>>> b
1
>>> a=2
>>> a
2
>>> b
1
```
* 自變賦值,如+=,-=,*=等。在自變賦值中,python僅計算一次,而普通寫法需計算兩次;自變賦值會修改原始對象,而不是創建一個新對象。
## Chapter 3\. Python內建對象類型
在Python中,所有數據都是對象,數據有各種類型,如數值型、列表型、字符串型等。除系統內建的數據類型外,程序員也可以創建自已的數據類型。以下主要介紹Python內建的數據類型。
## 3.1\. Number數值型
在python中,數值有四種類型,分別是整型、長整形、浮點型和復數。
* 整型---從-2147483648至2147483647,有符號位32位長,可表達的最大數為2^31-1。如:number=123,number1=-123。在數字前加0x或0X 前綴表示十六進制數,在數字前加前綴0表示八進制數,與C/C++ and perl一樣。
> 為方便起見,sys模塊包含一個maxint成員,該成員保留了整形變量的最大正數值。
```
>>> import sys
>>> print sys.maxint
2147483647
```
* 長整型---python支持任意長度的長整型,長整型的最大值和最小值由可用的內存確定。長整型數在數字常量尾加L or l,一般都是用L,因為小寫的l太容易與數字1混淆了。如:long=1232132131231232132132131L。
* 浮點數---python支持普通十進制和科學計數法表示的浮點數。如:number=123.456,nubmer1=123.2E10。浮點數在python中的存儲格式與C中的雙精度數相同。
* 復數---復數的實部和虛部用加號分開,虛部使用后綴j表示,如:number=1.2+2j
## 3.2\. String字符串型
* 字符串在python被看成是單個字符的序列,具有序列對象的特殊功能,字符串是固定的,不可變的。如:string="hello world"。
* 可在字符串中使用單引號和雙引號。如:string="I'm a boy"。
* 字符串內部的一個反斜杠“\”可允許把字符串放于多行:如:
```
>>> "test \
... python"
'test python'
```
* 使用三個單引號或雙引號可使字符串跨行顯示。如:
```
helptext="""this a help test.if you have any quesions.
please call me anytime.I will help you.I
like python.I hope so as you."""
```
* 使用“+”號可連接字符串。如:string = "hello" + "world",注意,不能將字符串與其它對象進行連接。如string = "ok" + 5。其實不用“+”號,直接用空格也可連接兩個字符串。如:string="hello" "world"。
* 可用“\*”號重復字符串,如:'hello'\*5會生成'hellohellohellohellohello'。
* 可用索引訪問字符串中的字符。如:string="hello world",print string[1]將顯示字符e。
* 字符串可用in或not in運算符來測試字符是不屬于一個字符串的成員。
* 可對字符串分片,如string="hello world",print string[6:]將顯示world。分片的格式為:
```
string[start:end]
```
分片和索引的規則如下:
* 返回的字符串包含從start起始到end但不包括end結束的所有字符。
* 若指定了start但未指定end,則一直向后分片,直至字符串結束。
* 若指定了end但未指定start,則從0開始分片直至end,但不包括end指定的字符。
* 若start和end為負數,則索引從字符串尾部開始算起,最后一個字符為-1。
python提供了一個string模塊來進行字符串處理。
### 3.2.1\. 字符串的格式化
象C 中的sprintf函數一樣,可以用“%”來格式化字符串。
**Table 3.1\. 字符串格式化代碼**
| 格式 | 描述 |
| --- | --- |
| %% | 百分號標記 |
| %c | 字符及其ASCII碼 |
| %s | 字符串 |
| %d | 有符號整數(十進制) |
| %u | 無符號整數(十進制) |
| %o | 無符號整數(八進制) |
| %x | 無符號整數(十六進制) |
| %X | 無符號整數(十六進制大寫字符) |
| %e | 浮點數字(科學計數法) |
| %E | 浮點數字(科學計數法,用E代替e) |
| %f | 浮點數字(用小數點符號) |
| %g | 浮點數字(根據值的大小采用%e或%f) |
| %G | 浮點數字(類似于%g) |
| %p | 指針(用十六進制打印值的內存地址) |
| %n | 存儲輸出字符的數量放進參數列表的下一個變量中 |
> %格式化符也可用于字典,可用%(name)引用字典中的元素進行格式化輸出。
> 負號指時數字應該是左對齊的,“0”告訴Python用前導0填充數字,正號指時數字總是顯示它的正負(+,-)符號,即使數字是正數也不例外。
> 可指定最小的字段寬度,如:"%5d" % 2。也可用句點符指定附加的精度,如:"%.3d" % 3。
### 3.2.2\. 轉義字符
在需要在字符中使用特殊字符時,python用反斜杠(\)轉義字符。如下表:
**Table 3.2\. python支持的轉義字符表**
| 轉義字符 | 描述 |
| --- | --- |
| \(在行尾時) | 續行符 |
| \\ | 反斜杠符號 |
| \' | 單引號 |
| \" | 雙引號 |
| \a | 響鈴 |
| \b | 退格(Backspace) |
| \e | 轉義 |
| \000 | 空 |
| \n | 換行 |
| \v | 縱向制表符 |
| \t | 橫向制表符 |
| \r | 回車 |
| \f | 換頁 |
| \oyy | 八進制數yy代表的字符,例如:\o12代表換行 |
| \xyy | 十進制數yy代表的字符,例如:\x0a代表換行 |
| \other | 其它的字符以普通格式輸出 |
### 3.2.3\. Unicode字符串
在python2.0中才完全支持Unicode字符串,Unicode字符采用16位(0---65535)值表示,能進行多語言支持。要使用Unicode字符串,只要在字符串前加上“u”即可。如:
```
>>> a=u"test"
>>> print a
test
```
原始Unicode字符串用ur前綴,如:
```
>>> u'hello world\0020'
u'hello world\x020'
>>> ur'hello world\0020'
u'hello world\\0020'
```
#### 3.2.3.1\. Unicode轉換
只要和Unicode連接,就會產生Unicode字串。如:
```
>>> 'help'
'help'
>>> 'help,' + u'python'
u'help,python'
```
對于ASCII(7位)兼容的字串,可和內置的str()函數把Unicode字串轉換成ASCII字串。如:
```
>>> str(u'hello world')
'hello world'
```
> 轉換非ASCII兼容的字串會出錯。編碼和譯碼字符串時的錯誤引發UnicodeError異常。
可使用encode()函數轉換Unicode字串格式:
```
u'unicode\xb1\xe0\xc2\xeb\xb2\xe2\xca\xd4'
>>> a.encode('utf-8') #轉換成utf-8,顯示結果會根據終端的字符集支持不同而不同,下面是在GB18030下的顯示結果
'unicode\xc2\xb1\xc3\xa0\xc3\x82\xc3\xab\xc2\xb2\xc3\xa2\xc3\x8a\xc3\x94'
```
可使用unicode()函數把字符串轉換成unicode格式,如:
```
>>> a=u'unicode測試'
>>> a
u'unicode\xb2\xe2\xca\xd4'
>>> a.encode('utf-8') #把unicode字串轉換成utf-8
'unicode\xc2\xb2\xc3\xa2\xc3\x8a\xc3\x94'
>>> b=a.encode('utf-8') #給變量b賦值
>>> b
'unicode\xc2\xb2\xc3\xa2\xc3\x8a\xc3\x94'
>>>unicode(b,'utf-8') #用unicode()函數把utf-8格式字串轉換回unicode格式。
u'unicode\xb2\xe2\xca\xd4' #和原始的這是a相同
```
ord()支持unicode,可以顯示特定字符的unicode號碼,如:
```
>>>ord('A')
65
```
使用unichr()函數可將unicode號碼轉換回unicode字符,如:
```
>>> unichr(65)
u'A'
```
### 3.2.4\. 原始字符串
有時我們并不想讓轉義字符生效,我們只想顯示字符串原來的意思,這就要用r和R來定義原始字符串。如:
```
print r'\t\r'
```
實際輸出為“\t\r”。
## 3.3\. List列表
* 列表是序列對象,可包含任意的Python數據信息,如字符串、數字、列表、元組等。列表的數據是可變的,我們可通過對象方法對列表中的數據進行增加、修改、刪除等操作。可以通過list(seq)函數把一個序列類型轉換成一個列表。列表的幾個例子:
* `list = [ "a", "b", "c" ]`,這是字符列表。
* `list = [ 1, 2, 3, 4 ]`,這是數字列表。
* `list = [ [1,2,3,4], ["a","b","c"] ]`,這是列表的列表。
* `list = [ (1,2,3,4), ("a","b","c") ]`,這是元組列表。
* list((1,2))把一個元組轉換成一個列表[1,2],list('test')可把字符串轉換成['t','e','s','t']列表。
* 訪問列表可通過索引來引用,如:list[0]將引用列表的第一個值。list[0:1]返回第一和第二個元素。
* 用range()和xrange()函數可自動生成列表,具體用法請參考“python參考篇”的內容。
* 可通過列表綜合來創建列表,該功能是在python2.0版本中新增加的。如果想對列表中的每個項進行運算并把結果存儲在一個新列表中,可者想創建一個僅包含特定滿足某種條件的項,采用該方法是很適合的。如:[x\*x for x in range(1,10)]會得到一個X的平方的新列表;我們還可添加if條件控制輸出,如:[x\*x for x in range(1,10) if x%2==0];還可在列表中使用多個for語句,如:
```
>>> [x+y for x in "123" for y in "abc"]
['1a', '1b', '1c', '2a', '2b', '2c', '3a', '3b', '3c']
```
x,y值可取列表或元組等,以構成更復雜的結構。
* “+”號可連接兩個列表。
* 訪問列表的列表(嵌套列表)可用list[1][0],這將訪問嵌套中的第二個列表的第一個元素。
* 可用數字與列表相乘以復制內容,如:list\*2會得到一個[1,2,3,4,1,2,3,4]的列表。注意,不能用列表與列表相乘。
* 由于列表是可變的,我們可用賦值語句進行操作,如:list[0] = 2。
* 列表對象方法可對列表進行操作,如列表內容的添加,刪除,排序等。如list.sort()可對list列表進行排序。
**Table 3.3\. 列表對象支持的方法**
```
| 方法 | 描述 |
| --- | --- |
| append(x) | 在列表尾部追加單個對象x。使用多個參數會引起異常。 |
| count(x) | 返回對象x在列表中出現的次數。 |
| extend(L) | 將列表L中的表項添加到列表中。返回None。 |
| Index(x) | 返回列表中匹配對象x的第一個列表項的索引。無匹配元素時產生異常。 |
| insert(i,x) | 在索引為i的元素前插入對象x。如list.insert(0,x)在第一項前插入對象。返回None。 |
| pop(x) | 刪除列表中索引為x的表項,并返回該表項的值。若未指定索引,pop返回列表最后一項。 |
| remove(x) | 刪除列表中匹配對象x的第一個元素。匹配元素時產生異常。返回None。 |
| reverse() | 顛倒列表元素的順序。 |
| sort() | 對列表排序,返回none。bisect模塊可用于排序列表項的添加和刪除。 |
```
## 3.4\. Tuple元組
Tuple(元組)和List(列表)很相似,但元組是不可變的。不能對元組中的元素進行添加,修改和刪除操作。如果需修改元組內容只有重建元組。元組用小括號來表示。如tuple=(1,2,3)。
* tuple=(1,),這是單個元素的元組表示,需加額外的逗號。
* tuple=1,2,3,4,這也可以是一個元組,在不使用圓括號而不會導致混淆時,Python允許不使用圓括號的元組。
* 和列表一樣,可對元組進行索引、分片、連接和重復。也可用len()求元組長度。
> 元組的索引用tuple[i]的形式,而不是tuple(i)。
* 和列表類似,使用tuple(seq)可把其它序列類型轉換成元組。
## 3.5\. 序列對象
上面介紹的字符串、列表和元組的對象類型均屬于稱為序列的Python對象。它是一種可使用數字化索引進行訪問其中元素的對象。
* 可用算術運算符聯接或重復序列。
* 比較運算符(<,<=,>,>=,!=,==)也可用于序列。
* 可通過下標(test[1]),切片(test[1:3])和解包來訪問序列的某部份。解包示例如下:
```
>>>s=1,2,3
>>>x,y,z=s
>>>print x,y,z
1,2,3
```
* in運算符可判斷當有對象是否序列對象成員,如:
```
>>>list = [1,2,3]
>>>1 in list
1
>>>4 in list
0
```
* 也可通過循環運算符對序列對象進行迭代操作。如:
```
for day in days:
print day
```
有關序列的處理函數請參考“python參考篇”相關內容,這里就不詳細講了。
## 3.6\. Dictionary字典
字典是一個用大括號括起來的鍵值對,字典元素分為兩部份,鍵(key)和值。字典是python中唯一內置映射數據類型。通過指定的鍵從字典訪問值。如:
```
monthdays = { "Jan":31, "Feb":28, "Mar":31, "Apr":30, "May":31, "Jun":30, "Jul":31, "Aug":31, "Sep":30, "Oct":31, "Nov":30,"Dec":31 }
```
* 字典可嵌套,可以在一個字典里包含另一個字典。如test={"test":{"mytest":10} }
* 可用鍵訪問字典,如monthdays["Jan"],可訪問值31。如果沒有找到指定的鍵,則解釋器會引起異常。
* 字典是可修改,如monthdays["Jan"]=30,可把Jan的值由31改為30。如monthdays["test"]=30可添加一個新鍵值對。
* del monthdays["test"]可刪除字典條目。
* 字典不屬序列對象,所以不能進行連接和相乘操作。字典是沒有順序的。
* 字典提供keys和values方法,用來返回字典中定義的所有鍵和值。
* 和列表一樣,字典也提供了對象方法來對字典進行操作。
**Table 3.4\. 字典方法**
```
| 方法 | 描述 |
| --- | --- |
| has_key(x) | 如果字典中有鍵x,則返回真。 |
| keys() | 返回字典中鍵的列表 |
| values() | 返回字典中值的列表。 |
| items() | 返回tuples的列表。每個tuple由字典的鍵和相應值組成。 |
| clear() | 刪除字典的所有條目。 |
| copy() | 返回字典高層結構的一個拷貝,但不復制嵌入結構,而只復制對那些結構的引用。 |
| update(x) | 用字典x中的鍵值對更新字典內容。 |
| get(x[,y]) | 返回鍵x,若未找到該鍵返回none,若提供y,則未找到x時返回y。 |
```
## 3.7\. File文件
可用內置的open()函數對文件進行操作。如:
```
input = open("test.txt")
for line in input.readlines():
print line
input.close()
```
## 3.8\. 理解引用
* Python把一塊數據存儲在對象中,變量是對象的唯一引用;它們是計算機內存中特殊地點的名字。所有對象都具有唯一的身份號、類型和值。對象的類型不會改變,對于可變類型而言,它的值是可變的。id(obj)函數可用于檢索對象的身份,也就是內存中的對象的地址。
* 每個對象都包含引用計數器,它記錄當前有多少個變量正在引用該對象。當給對象指定一個變量或使對象成為列表或其它包容器的成員時,引用計數就增加;當從包容器中撤消、重新分配或刪除對象時,引用計數減少。當引用計數達到0值時(即沒有任何變量引用這個對象),python的回收機制會自動回收它使用的內存。注意,del可用來刪除變量,但不能刪除對象。
> sys.gettrefcount(obj)函數可返回給定對象的引用計數。
## 3.9\. copy and deepcopy
通過給列表分配一個變量能創建對列表的引用,如果要創建列表的副本就要理解淺副本和深副本的概念。
* 列表或其他包容器對象的淺副本(Shallow)能夠生成對象本身的副本,但也會創建對由列表包含的對象的引用。可用分片(object[:])和copy模塊的copy(obj)函數創建。
* 列表或其他對象包容器對象的深副本能夠生成對象本身的副本,并遞歸地生成所有子對象的副本。可用copy模塊的deepcopy(obj)函數創建。
比較兩種副本,一般情況下表現一樣,但當列表內包含另一個列表的情況下,父列表的淺副本將包含對子列表引用,而不是獨立副本。其結果是,當更改內部列表時,從父列表的兩個副本中都可見,如:
```
>>> a=[1,2,3,[4,5]]
>>> b=a[:]
>>> b
[1, 2, 3, [4, 5]]
>>> a[3].remove(4)
>>> a
[1, 2, 3, [5]]
>>> b
[1, 2, 3, [5]]
```
如果是深副本,就不會出現這種情況。如:
```
>>> a=[1,2,3,[4,5]]
>>> b=copy.deepcopy(a)
>>> b
[1, 2, 3, [4, 5]]
>>> a[3].remove(4)
>>> a
[1, 2, 3, [5]]
>>> b
[1, 2, 3, [4, 5]]
```
## 3.10\. 標識數據類型
可通過type(obj)函數標識數據類型,如:
```
>>> type(a)
<type 'list'>
>>> type(copy)
<type 'module'>
>>> type(1)
<type 'int'>
```
types模塊包含Python的內置數據類型的類型對象。如:
```
>>> import types
>>> types.ListType
<type 'list'>
>>> types.IntType
<type 'int'>
```
## 3.11\. 數組對象
數組對象與列表類似,但數組只包含某些類型的簡單數據。所以當數據較簡單,且要求性能好的情況下,使用數組是一個好的選擇。
**Table 3.5\. 數組類型代碼**
| 代碼 | 等價的C類型 | 以字節為單位的最小尺寸 |
| --- | --- | --- |
| c | char | 1 |
| b(B) | byte(unsigned byte) | 1 |
| h(H) | short(unsigned short) | 2 |
| i(I) | int(unsigned int) | 2 |
| l(L) | long(unsigned long) | 4 |
| f | float | 4 |
| d | double | 8 |
數組創建方法如下:
```
>>> import array
>>> z=array.array("b")
>>> z.append(1)
>>> z
array('b', [1])
```
數組的itemsize和typecode成員可分別檢索數組項的大小和數組對象的類型代碼,如:
```
>>> z.itemsize
1
>>> z.typecode
'b'
```
### 3.1\. 數組類型與其它數據類型的轉換
* tolist()方法可把數組轉換為列表,如:
```
>>> z.tolist()
[1, 2, 3]
```
fromlist(list)方法可把列表項附加到數組的末尾,如:
```
>>> z.fromlist([10,11])
>>> z
array('b', [1, 2, 3, 10, 11])
```
> 如添加的列表類型與數組類型不同,則fromlist(list)不會把任何項添加到數組對象中。
* tostring()方法,可以把數組轉換為字節的序列,如:
```
>>> z.tostring()
'\x01\x02\x03\n\x0b'
```
fromstring(list)方法剛好與tostring()相反,它獲取一個字節串,并把它們轉換為數組的值。如:
```
>>> z.fromstring("\x0b")
>>> z
array('b', [1, 2, 3, 10, 11, 11])
```
* tofile(file)方法可把數組轉換為字節的序列,并把它們寫入文件,如:
```
>>> f=open("aa","wb")
>>> z.tofile(f)
>>> f.close()
```
fromfile(file,count)方法用于從文件對象中讀取特定數目的項,并把它們附加到數組中,如:
```
>>> z.fromfile(open("aa","rb"),2)
>>> z
array('b', [1, 2, 3, 10, 11, 11, 1, 2])
```
當取數項大于文件數據項時,formfile會產生EOFError異常。
* 數組對象支持列表中的很多相同函數和方法:len,append等。訪問成員的方法也可列表一樣,可用下標和分片。
## Chapter 4\. 控制語句
流程控制是程序設計中一個重要的內容,Python支持三種不同的控制結構:if,for和while。
* if語句判斷表達式是否為真,如果為真則執行指定語句。if語句的格式如下:
```
if EXPRESSION1:
STATEMENT1
elif EXPRESSION2:
STATEMENT2
else:
STATEMENT3
```
如果第一個表達式為真,則執行statement1,否則進行進一步的測試,如果第二個表達式為真則執行statement2,否則執行statement3。
> 注意語句的縮進量要保持一致。在python中沒有switch和case語句,我們可通過多重elif來達到相同的效果。
示例:
```
#!/usr/bin/env python
mytest = raw_input("please input a number:")
mytest = int(mytest)
if mytest == 10:
print "you input number is ten."
elif mytest == 20:
print "you input number is twenty."
else:
print "another number."
```
腳本的執行效果:
```
t03:~# python test.py
please input a number:10
you input number is ten.
t03:~# python test.py
please input a number:20
you input number is twenty.
t03:~# python test.py
please input a number:777
another number.
```
* while進行循環控制,它對表達式進行測試,如果為真,則循環執行循環體。格式如下:
```
while EXPRESSION:
STATEMENT
else:
STATEMENT
```
如果測試為假,則會執行else塊。如果循環被中斷(break),則else塊不會執行。
示例:
```
>>> a = 0
>>> while a > 5:
... a = a + 1
... print a
... else:
... print "a's value is five"
...
1
2
3
4
5
a's value is five
```
* for循環可遍歷對象,并可進行迭代操作。語名格式如下:
```
for TARGET in OBJECTS:
STATEMENT
else:
STATEMENT
```
和while一樣,在循環正常退出時,會執行else塊。
示例:
```
>>> mylist = "for statement"
>>> for word in mylist:
... print word
... else:
... print "End list"
...
f
o
r
s
t
a
t
e
m
e
n
t
End list
```
* 在循環的過程中,我們可使用循環控制語句來控制循環的執行。有三個控制語句,分別是break、continue和pass。它們的作用分別是:
* break語句會立即退出當前循環,不會執行else塊的內容。
示例:
```
>>> mylist = ["zope","python","perl","Linux"]
>>> for technic in mylist:
... if technic == "perl":
... break
... else:
... print technic
...
zope
python
```
* continue語句會忽略后面的語句,強制進入下一次循環。
示例:
```
>>> mylist = ["zope","python","perl","Linux"]
>>> for technic in mylist:
... if technic == "perl":
... continue
... else:
... print technic
...
zope
python
Linux
```
* pass不做任何事情。
示例:
```
>>> for technic in mylist:
... if technic == "perl":
... pass
... else:
... print technic
...
zope
python
Linux
```
## Chapter 5\. 函數
函數是一個能完成特定功能的代碼塊,可在程序中重復使用,減少程序的代碼量和提高程序的執行效率。在python中函數定義語法如下:
```
def function_name(arg1,arg2[,...]):
statement
[return value]
```
> 返回值不是必須的,如果沒有return語句,則Python默認返回值None。
函數名的命名規則:
* 函數名必須以下劃線或字母開頭,可以包含任意字母、數字或下劃線的組合。不能使用任何的標點符號;
* 函數名是區分大小寫的。
* 函數名不能是保留字。
Python使用名稱空間的概念存儲對象,這個名稱空間就是對象作用的區域, 不同對象存在于不同的作用域。下面是不同對象的作用域規則:
* 每個模塊都有自已的全局作用域。
* 函數定義的對象屬局部作用域,只在函數內有效,不會影響全局作用域中的對象。
* 賦值對象屬局部作用域,除非使用global關鍵字進行聲明。
LGB規則是Python查找名字的規則,下面是LGB規則:
* 大多數名字引用在三個作用域中查找:先局部(Local),次之全局(Global),再次之內置(Build-in)。
```
>>> a=2
>>> b=2
>>> def test(b):
... test=a*b
... return test
>>>print test(10)
20
```
b在局部作用域中找到,a在全局作用域中找到。
* 如想在局部作用域中改變全局作用域的對象,必須使用global關鍵字。
```
#沒用global時的情況
>>> name="Jims"
>>> def set():
... name="ringkee"
...
>>> set()
>>> print name
Jims
#使用global后的情況
>>> name="Jims"
>>> def set1():
... global name
... name="ringkee"
...
>>> set1()
>>> print name
ringkee
```
* 'global'聲明把賦值的名字映射到一個包含它的模塊的作用域中。
函數的參數是函數與外部溝通的橋梁,它可接收外部傳遞過來的值。參數傳遞的規則如下:
* 在一個函數中對參數名賦值不影響調用者。
```
>>> a=1
>>> def test(a):
... a=a+1
... print a
...
>>> test(a)
2
>>> a
1 # a值不變
```
* 在一個函數中改變一個可變的對象參數會影響調用者。
```
>>> a=1
>>> b=[1,2]
>>> def test(a,b):
... a=5
... b[0]=4
... print a,b
...
>>> test(a,b)
5 [4, 2]
>>> a
1
>>> b
[4, 2] # b值已被更改
```
參數是對象指針,無需定義傳遞的對象類型。如:
```
>>> def test(a,b):
... return a+b
...
>>> test(1,2) #數值型
3
>>> test("a","b") #字符型
'ab'
>>> test([12],[11]) #列表
[12, 11]
```
函數中的參數接收傳遞的值,參數可分默認參數,如:
```
def function(ARG=VALUE)
```
元組(Tuples)參數:
```
def function(*ARG)
```
字典(dictionary)參數:
```
def function(**ARG)
```
一些函數規則:
* 默認值必須在非默認參數之后;
* 在單個函數定義中,只能使用一個tuple參數(\*ARG)和一個字典參數(\*\*ARG)。
* tuple參數必須在連接參數和默認參數之后。
* 字典參數必須在最后定義。
## 5.1\. 常用函數
* abs(x)
abs()返回一個數字的絕對值。如果給出復數,返回值就是該復數的模。
```
>>>print abs(-100)
100
>>>print abs(1+2j)
2.2360679775
```
* callable(object)
callable()函數用于測試對象是否可調用,如果可以則返回1(真);否則返回0(假)。可調用對象包括函數、方法、代碼對象、類和已經定義了“調用”方法的類實例。
```
>>> a="123"
>>> print callable(a)
0
>>> print callable(chr)
1
```
* cmp(x,y)
cmp()函數比較x和y兩個對象,并根據比較結果返回一個整數,如果x<y,則返回-1;如果x>y,則返回1,如果x==y則返回0。
```
>>>a=1
>>>b=2
>>>c=2
>>> print cmp(a,b)
-1
>>> print cmp(b,a)
1
>>> print cmp(b,c)
0
```
* divmod(x,y)
divmod(x,y)函數完成除法運算,返回商和余數。
```
>>> divmod(10,3)
(3, 1)
>>> divmod(9,3)
(3, 0)
```
* isinstance(object,class-or-type-or-tuple) -> bool
測試對象類型
```
>>> a='isinstance test'
>>> b=1234
>>> isinstance(a,str)
True
>>> isinstance(a,int)
False
>>> isinstance(b,str)
False
>>> isinstance(b,int)
True
```
* len(object) -> integer
len()函數返回字符串和序列的長度。
```
>>> len("aa")
2
>>> len([1,2])
2
```
* pow(x,y[,z])
pow()函數返回以x為底,y為指數的冪。如果給出z值,該函數就計算x的y次冪值被z取模的值。
```
>>> print pow(2,4)
16
>>> print pow(2,4,2)
0
>>> print pow(2.4,3)
13.824
```
* range([lower,]stop[,step])
range()函數可按參數生成連續的有序整數列表。
```
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1,10)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1,10,2)
[1, 3, 5, 7, 9]
```
* round(x[,n])
round()函數返回浮點數x的四舍五入值,如給出n值,則代表舍入到小數點后的位數。
```
>>> round(3.333)
3.0
>>> round(3)
3.0
>>> round(5.9)
6.0
```
* type(obj)
type()函數可返回對象的數據類型。
```
>>> type(a)
<type 'list'>
>>> type(copy)
<type 'module'>
>>> type(1)
<type 'int'>
```
* xrange([lower,]stop[,step])
xrange()函數與range()類似,但xrnage()并不創建列表,而是返回一個xrange對象,它的行為與列表相似,但是只在需要時才計算列表值,當列表很大時,這個特性能為我們節省內存。
```
>>> a=xrange(10)
>>> print a[0]
0
>>> print a[1]
1
>>> print a[2]
2
```
## 5.2\. 內置類型轉換函數
* chr(i)
chr()函數返回ASCII碼對應的字符串。
```
>>> print chr(65)
A
>>> print chr(66)
B
>>> print chr(65)+chr(66)
AB
```
* complex(real[,imaginary])
complex()函數可把字符串或數字轉換為復數。
```
>>> complex("2+1j")
(2+1j)
>>> complex("2")
(2+0j)
>>> complex(2,1)
(2+1j)
>>> complex(2L,1)
(2+1j)
```
* float(x)
float()函數把一個數字或字符串轉換成浮點數。
```
>>> float("12")
12.0
>>> float(12L)
12.0
>>> float(12.2)
12.199999999999999
```
* hex(x)
hex()函數可把整數轉換成十六進制數。
```
>>> hex(16)
'0x10'
>>> hex(123)
'0x7b'
```
* long(x[,base])
long()函數把數字和字符串轉換成長整數,base為可選的基數。
```
>>> long("123")
123L
>>> long(11)
11L
```
* list(x)
list()函數可將序列對象轉換成列表。如:
```
>>> list("hello world")
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> list((1,2,3,4))
[1, 2, 3, 4]
```
* int(x[,base])
int()函數把數字和字符串轉換成一個整數,base為可選的基數。
```
>>> int(3.3)
3
>>> int(3L)
3
>>> int("13")
13
>>> int("14",15)
19
```
* min(x[,y,z...])
min()函數返回給定參數的最小值,參數可以為序列。
```
>>> min(1,2,3,4)
1
>>> min((1,2,3),(2,3,4))
(1, 2, 3)
```
* max(x[,y,z...])
max()函數返回給定參數的最大值,參數可以為序列。
```
>>> max(1,2,3,4)
4
>>> max((1,2,3),(2,3,4))
(2, 3, 4)
```
* oct(x)
oct()函數可把給出的整數轉換成八進制數。
```
>>> oct(8)
'010'
>>> oct(123)
'0173'
```
* ord(x)
ord()函數返回一個字符串參數的ASCII碼或Unicode值。
```
>>> ord("a")
97
>>> ord(u"a")
97
```
* str(obj)
str()函數把對象轉換成可打印字符串。
```
>>> str("4")
'4'
>>> str(4)
'4'
>>> str(3+2j)
'(3+2j)'
```
* tuple(x)
tuple()函數把序列對象轉換成tuple。
```
>>> tuple("hello world")
('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd')
>>> tuple([1,2,3,4])
(1, 2, 3, 4)
```
## 5.3\. 序列處理函數
* 常用函數中的len()、max()和min()同樣可用于序列。
* filter(function,list)
調用filter()時,它會把一個函數應用于序列中的每個項,并返回該函數返回真值時的所有項,從而過濾掉返回假值的所有項。
```
>>> def nobad(s):
... return s.find("bad") == -1
...
>>> s = ["bad","good","bade","we"]
>>> filter(nobad,s)
['good', 'we']
```
這個例子通過把nobad()函數應用于s序列中所有項,過濾掉所有包含“bad”的項。
* map(function,list[,list])
map()函數把一個函數應用于序列中所有項,并返回一個列表。
```
>>> import string
>>> s=["python","zope","linux"]
>>> map(string.capitalize,s)
['Python', 'Zope', 'Linux']
```
map()還可同時應用于多個列表。如:
```
>>> import operator
>>> s=[1,2,3]; t=[3,2,1]
>>> map(operator.mul,s,t) # s[i]*t[j]
[3, 4, 3]
```
如果傳遞一個None值,而不是一個函數,則map()會把每個序列中的相應元素合并起來,并返回該元組。如:
```
>>> a=[1,2];b=[3,4];c=[5,6]
>>> map(None,a,b,c)
[(1, 3, 5), (2, 4, 6)]
```
* reduce(function,seq[,init])
reduce()函數獲得序列中前兩個項,并把它傳遞給提供的函數,獲得結果后再取序列中的下一項,連同結果再傳遞給函數,以此類推,直到處理完所有項為止。
```
>>> import operator
>>> reduce(operator.mul,[2,3,4,5]) # ((2*3)*4)*5
120
>>> reduce(operator.mul,[2,3,4,5],1) # (((1*2)*3)*4)*5
120
>>> reduce(operator.mul,[2,3,4,5],2) # (((2*2)*3)*4)*5
240
```
* zip(seq[,seq,...])
zip()函數可把兩個或多個序列中的相應項合并在一起,并以元組的格式返回它們,在處理完最短序列中的所有項后就停止。
```
>>> zip([1,2,3],[4,5],[7,8,9])
[(1, 4, 7), (2, 5, 8)]
```
如果參數是一個序列,則zip()會以一元組的格式返回每個項,如:
```
>>> zip((1,2,3,4,5))
[(1,), (2,), (3,), (4,), (5,)]
>>> zip([1,2,3,4,5])
[(1,), (2,), (3,), (4,), (5,)]
```
## Chapter 6\. 模塊
模塊可把一個復雜的程序按功能分開,分別存放到不同文件中,使程序更容易維護和管理。在Python中的模塊是一個以.py結尾的Python代碼文件。可通過import命令輸入,如:
```
import sys
```
import會完成以下三個操作:
* 創建新的名稱空間(namespace),該名稱空間中擁有輸入模塊中定義的所有對象;
* 執行模塊中的代碼;
* 創建該名稱空間的變量名。
import語句可同時輸入多個模塊,如:
```
import os,sys,system
```
也可寫成:
```
import os
import sys
import system
```
有些模塊的名稱很長,我們可在輸入時給它起個簡單的別名,這樣在使用模塊中的對象就方便很多,如:
```
import ftplib as ftp
```
有時我們可能只想使用模塊中某個對象,又不想把整個模塊輸入,則可以用from...import語句輸入特定對象。如:
```
from ftplib import FTP
```
這樣,我們就可直接使用FTP(),而不用帶前綴。
如果裝載模塊出錯,會引發ImportError異常。我們可捕獲該異常進行相應處理。
Python腳本和模塊都是一個以.py結束的文件,那程序是如何判斷一個.py文件是作為腳本還是模塊呢?關鍵是一個名為\_\_name\_\_的變量,如果它的值是\_\_main\_\_,則不能作為模塊,只能作為腳本直接運行。所以在很多腳本的最后都有一段類似下面的語句,限制只能以腳本方式運行,不作為模塊:
```
if __name__ == '__main__':
main()
```
幾個功能相近的模塊我們可組成一個Python包,存放到一個目錄結構中,通過輸入包的路徑來調用對象。要定義包,就要建一個與包名同名的目錄,接著在該目錄下創建\_\_init\_\_.py文件。該文件是包的初始化文件,可以為空,也可定義一個代碼。例如一個WebDesign包的目錄如下:
```
/WebDesign
__init_.py
design.py
draw.py
...
```
我們可通過以下語句輸入design模塊:
```
import WebDesign.design
```
## 6.1\. String模塊
* replace(string,old,new[,maxsplit])
字符串的替換函數,把字符串中的old替換成new。默認是把string中所有的old值替換成new值,如果給出maxsplit值,還可控制替換的個數,如果maxsplit為1,則只替換第一個old值。
```
>>>a="11223344"
>>>print string.replace(a,"1","one")
oneone2223344
>>>print string.replace(a,"1","one",1)
one12223344
```
* capitalize(string)
該函數可把字符串的首個字符替換成大字。
```
>>> import string
>>> print string.capitalize("python")
Python
```
* split(string,sep=None,maxsplit=-1)
從string字符串中返回一個列表,以sep的值為分界符。
```
>>> import string
>>> ip="192.168.3.3"
>>> ip_list=string.split(ip,'.')
>>> print ip_list
['192', '168', '3', '3']
```
* join(string[,sep])
返回用sep連接的字串,默認的sep是空格。
```
>>> import string
>>> a = ['a','b','c']
>>> b = string.join(a,'-')
>>> b
'a-b-c'
>>> a
['a', 'b', 'c']
```
## 6.2\. time模塊
內置模塊time包含很多與時間相關函數。我們可通過它獲得當前的時間和格式化時間輸出。
* time(),以浮點形式返回自Linux新世紀以來經過的秒數。在linux中,00:00:00 UTC, January 1, 1970是新紀元的開始。
```
>>> time.time()
1150269086.6630149
>>> time.ctime(1150269086.6630149)
>>> 'Wed Jun 14 15:11:26 2006'
```
* ctime([sec]),把秒數轉換成日期格式,如果不帶參數,則顯示當前的時間。
```
>>> import time
>>> time.ctime()
>>> 'Wed Jun 14 15:02:50 2006'
>>> time.ctime(1138068452427683)
'Sat Dec 14 04:51:44 1901'
```
* sleep(secs),定時。
```
>>> time.sleep(10)
>>> #10秒后才會出現>>>提示符
```
## Chapter 7\. 類
類是面向對象編程的一個重要概念。通過類的創建和繼承,可重用代碼,減少代碼復雜度。Python是一種面向對象的腳本語言,用class語句可創建類,語法規則如下:
```
class classnmae([class_parent,...]):
...
def method():
...
...
```
一個例子:
```
#!/usr/bin/python
#-*- encoding:utf-8 -*-
class test: #定義一個test類
desc = "這是一個測試類。" #在類中定義一個屬性desc
def __init__(self,name1): #對象構造函數,初始化類
self.name1 = name1
def show(self,name2): #在類中定義一個方法show()
print "hello world"
print 'name1:',self.name1
print 'name2:',name2
instance = test('這是傳遞給name1的值') #生成test類的實例對象instance
print instance.desc #調用類中的desc屬性
instance.show('這是傳遞給name2的值') #調用類中的show()方法
```
把該腳本命名為test.py,并用chmod +x test.py使腳本有執行的權限 ,運行該腳本結果如下:
```
debian:~/python# ./test.py
這是一個測試類。
hello world
name1: 這是傳遞給name1的值
name2: 這是傳遞給name2的值
```
這里只是Python語言中類的一個簡單介紹。詳細介紹可參考網站上自由文檔欄目中的Python資料。
## Chapter 8\. 異常處理
Python的異常處理能力是很強大的,可向用戶準確反饋出錯信息。在Python中,異常也是對象,可對它進行操作。所有異常都是基類Exception的成員。異常處理的try語法有兩種,一種是:
```
try:
block
except [exception,[data...]]:
block
else:
block
```
該種異常處理語法的規則是:
* 執行try下的語句,如果引發異常,則執行過程會跳到第一個except語句。
* 如果第一個except中定義的異常與引發的異常匹配,則執行該except中的語句。
* 如果引發的異常不匹配第一個except,則會搜索第二個except,允許編寫的except數量沒有限制。
* 如果所有的except都不匹配,則異常會傳遞到下一個調用本代碼的最高層try代碼中。
* 如果沒有發生異常,則執行else塊代碼。
try語句的第二種語法是:
```
try:
block
finally:
block
```
該語句的執行規則是:
* 執行try下的代碼。
* 如果發生異常,在該異常傳遞到下一級try時,執行finally中的代碼。
* 如果沒有發生異常,則執行finally中的代碼。
第二種try語法在無論有沒有發生異常都要執行代碼的情況下是很有用的。例如我們在python中打開一個文件進行讀寫操作,我在操作過程中不管是否出現異常,最終我都是要把該文件關閉的。
除了系統引發的異常外,我們還可用raise語句手工引發一個異常:
```
raise [exception[,data]]
```
## Chapter 9\. 文件處理
文件是我們儲存信息的地方,我們經常要對文件進行讀、寫、刪除等的操作,在Python中,我們可用Python提供的函數和方法方便地操作文件。
## 9.1\. 文件處理的函數和方法
使用Open()函數可打開文件,語法格式如下:
```
file_handler = open(filename,[,mode[,bufsize]]
```
filename是你要操作的文件名,如果不在當前路徑,需指出具體路徑。mode是打開文件的模式,表示你要如何操作文件,bufsize表示是否使用緩存。
**Table 9.1\. mode**
| 模式 | 描述 |
| --- | --- |
| r | 以讀方式打開文件,可讀取文件信息。 |
| w | 以寫方式打開文件,可向文件寫入信息。 |
| a | 以追加方式打開文件,文件指針自動移到文件尾。 |
| r+ | 以讀寫方式打開文件,可對文件進行讀和寫操作。 |
| w+ | 消除文件內容,然后以讀寫方式打開文件。 |
| a+ | 以讀寫方式打開文件,并把文件指針移到文件尾。 |
| b | 以二進制模式打開文件,而不是以文本模式。該模式只對Windows或Dos有效,類Unix的文件是用二進制模式進行操作的。 |
**Table 9.2\. bufsize**
| bufsize取值 | 描述 |
| --- | --- |
| 0 | 禁用緩沖 |
| 1 | 行緩沖 |
| >1 | 指定緩沖區的大小 |
| <1 | 系統默認的緩沖區大小 |
open()函數返回一個文件對象,我們可通過read()或write()函數對文件進行讀寫操作,下面是一些文件對象方法:
**Table 9.3\. 文件對象方法**
| 方法 | 描述 |
| --- | --- |
| f.close() | 關閉文件,記住用open()打開文件后一定要記得關閉它,否則會占用系統的可打開文件句柄數。 |
| f.fileno() | 獲得文件描述符 |
| f.flush() | 刷新輸出緩存 |
| f.isatty() | 如果文件是一個交互終端,則返回True,否則返回False。 |
| f.read([count]) | 讀出文件,如果有count,則讀出count個字節。 |
| f.readline() | 讀出一行信息。 |
| f.readlines() | 讀出所有行,也就是讀出整個文件的信息。 |
| f.seek(offset[,where]) | 把文件指針移動到相對于where的offset位置。offset為0表示文件開始處,這是默認值 ;1表示當前位置;2表示文件結尾。 |
| f.tell() | 獲得文件指針位置。 |
| f.truncate([size]) | 截取文件,使文件的大小為size。 |
| f.write(string) | 把string字符串寫入文件。 |
| f.writelines(list) | 把list中的字符串一行一行地寫入文件。 |
## 9.2\. 示例
* 文件的打開或創建
```
#!/usr/bin/env python
#-*- encoding:UTF-8 -*-
filehandler = open('test.txt','w') #以寫模式打開文件,如果文件不存在則創建
filehandler.write('this is a file open/create test.\nthe second line.')
filehandler.close()
```
```
#!/usr/bin/env python
#-*- encoding:UTF-8 -*-
filehandler = open('test.txt','a') #以追加模式打開文件,如果文件不存在則創建
filehandler.write('\nappend the text in another line.\n')
filehandler.close()
```
* 讀取文件
```
#!/usr/bin/env python
#-*- encoding:UTF-8 -*-
filehandler = open('test.txt','r') #以讀方式打開文件,rb為二進制方式(如圖片或可執行文件等)
print 'read() function:' #讀取整個文件
print filehandler.read()
print 'readline() function:' #返回文件頭,讀取一行
filehandler.seek(0)
print filehandler.readline()
print 'readlines() function:' #返回文件頭,返回所有行的列表
filehandler.seek(0)
print filehandler.readlines()
print 'list all lines' #返回文件頭,顯示所有行
filehandler.seek(0)
textlist = filehandler.readlines()
for line in textlist:
print line
print 'seek() function' #移位到第32個字符,從33個字符開始顯示余下內容
filehandler.seek(32)
print filehandler.read()
print 'tell() function' #移位到文件頭,從頭開始顯示2位字符
filehandler.seek(0)
print filehandler.readline() #顯示第一行內容
print filehandler.tell() #顯示當前位置
print filehandler.readline() #顯示第二行內容
print filehandler.read() #顯示余下所有內容
filehandler.close() #關閉文件句柄
```
* 文件系統操作
```
#!/usr/bin/env python
#-*- encoding:utf-8 -*-
import os,fnmatch,glob
for fileName in os.listdir ( '/root' ): #列出/root目錄內容,不包括.和..
print fileName
os.mkdir('py') #在當前目錄下創建一個py目錄,且只能創建一層
os.rmdir( 'py') #在當前目錄下刪除py目錄,且只能刪除一層
os.makedirs('py/aa') #可創建多層目錄
os.removedirs('py/aa') #可刪除多層目錄
print 'demonstration fnmatch module'
for fileName in os.listdir ( '/root/python/file' ):
if fnmatch.fnmatch(fileName,'*.txt'): #利用UNIX風格的通配,只顯示后綴為txt的文件
print fileName
print 'demonstration glob module'
for fileName in glob.glob ( '*.txt' ): #利用UNIX風格的通配,只顯示后綴為txt的文件
print fileName
```
* 獲取文件狀態
```
#!/usr/bin/env python
#-*- encoding:UTF-8 -*-
import os,time,stat
fileStats = os.stat ( 'test.txt' ) #獲取文件/目錄的狀態
fileInfo = {
'Size':fileStats [ stat.ST_SIZE ], #獲取文件大小
'LastModified':time.ctime( fileStats [ stat.ST_MTIME ] ), #獲取文件最后修改時間
'LastAccessed':time.ctime( fileStats [ stat.ST_ATIME ] ), #獲取文件最后訪問時間
'CreationTime':time.ctime( fileStats [ stat.ST_CTIME ] ), #獲取文件創建時間
'Mode':fileStats [ stat.ST_MODE ] #獲取文件的模式
}
#print fileInfo
for field in fileInfo: #顯示對象內容
print '%s:%s' % (field,fileInfo[field])
#for infoField,infoValue in fileInfo:
# print '%s:%s' % (infoField,infoValue)
if stat.S_ISDIR ( fileStats [ stat.ST_MODE ] ): #判斷是否路徑
print 'Directory. '
else:
print 'Non-directory.'
if stat.S_ISREG ( fileStats [ stat.ST_MODE ] ): #判斷是否一般文件
print 'Regular file.'
elif stat.S_ISLNK ( fileStats [ stat.ST_MODe ] ): #判斷是否鏈接文件
print 'Shortcut.'
elif stat.S_ISSOCK ( fileStats [ stat.ST_MODe ] ): #判斷是否套接字文件
print 'Socket.'
elif stat.S_ISFIFO ( fileStats [ stat.ST_MODe ] ): #判斷是否命名管道
print 'Named pipe.'
elif stat.S_ISBLK ( fileStats [ stat.ST_MODe ] ): #判斷是否塊設備
print 'Block special device.'
elif stat.S_ISCHR ( fileStats [ stat.ST_MODe ] ): #判斷是否字符設置
print 'Character special device.'
```
```
#!/usr/bin/env python
#-*- encoding:UTF-8 -*-
import os.path
fileStats = 'test.txt'
if os.path.isdir ( fileStats ): #判斷是否路徑
print 'Directory.'
elif os.path.isfile ( fileStats ): #判斷是否一般文件
print 'File.'
elif os.path.islink ( fileStats ): #判斷是否鏈接文件
print 'Shortcut.'
elif os.path.ismount ( fileStats ): #判斷是否掛接點
print 'Mount point.'
```
stat模塊描述了os.stat(filename)返回的文件屬性列表中各值的意義。我們可方便地根據stat模塊存取os.stat()中的值。
* 串行化文件
```
#!/usr/bin/env python
#-*- encoding:UTF-8 -*-
import pickle
filehandler = open('pickle.txt','w')
text = ['this is a pickle demonstrate','aa','bb']
pickle.dump(text,filehandler) #把text的內容序列化后保存到pickle.txt文件中
filehandler.close()
filehandler2 = open('pickle.txt')
textlist = pickle.load(filehandler2) #還原序列化字符串
print textlist
filehandler2.close()
#cpickle是用C寫的pickle模塊,比標準的pickle速度快很多,使用方法同pickle。
```
* 內存文件
```
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import StringIO
fileHandle = StringIO.StringIO ( "Let freedom ring." ) #create file in memory
print fileHandle.read() # "Let freedom ring."
fileHandle.close()
#cStringIO是用C寫的StringIO模塊,執行速度比StringIO快。
```
shutil模塊是一個高級的文件處理模塊,可實現文件的拷貝、刪除等操作。
## Chapter 10\. 正則表達式
正則表達式是一個很有用的工具,可處理復雜的字符匹配和替換工作。在Python中內置了一個re模塊以支持正則表達式。
正則表達式有兩種基本的操作,分別是匹配和替換。
* 匹配就是在一個文本字符串中搜索匹配一特殊表達式;
* 替換就是在一個字符串中查找并替換匹配一特殊表達式的字符串。
## 10.1\. 基本元素
正則表達式定義了一系列的特殊字符元素以執行匹配動作。
**Table 10.1\. 正則表達式基本字符**
| 字符 | 描述 |
| --- | --- |
| text | 匹配text字符串 |
| . | 匹配除換行符之外的任意一個單個字符 |
| ^ | 匹配一個字符串的開頭 |
| $ | 匹配一個字符串的末尾 |
在正則表達式中,我們還可用匹配限定符來約束匹配的次數。
**Table 10.2\. 匹配限定符**
| 最大匹配 | 最小匹配 | 描述 |
| --- | --- | --- |
| * | * | 重復匹配前表達式零次或多次 |
| + | + | 重復匹配前表達式一次或多次 |
| ? | ? | 重復匹配前表達式零次或一次 |
| {m} | {m} | 精確重復匹配前表達式m次 |
| {m,} | {m,} | 至少重復匹配前表達式m次 |
| {m,n} | {m,n} | 至少重復匹配前表達式m次,至多重復匹配前表達式n次 |
據上所述,".\*"為最大匹配,能匹配源字符串所有能匹配的字符串。".\* "為最小匹配,只匹配第一次出現的字符串。如:d.\*g能匹配任意以d開頭,以g結尾的字符串,如"debug"和"debugging",甚至"dog is walking"。而d.\* g只能匹配"debug",在"dog is walking"字符串中,則只匹配到"dog "。
在一些更復雜的匹配中,我們可用到組和運算符。
**Table 10.3\. 組和運算符**
| 組 | 描述 |
| --- | --- |
| [...] | 匹配集合內的字符,如[a-z],[1-9]或[,./;'] |
| [^...] | 匹配除集合外的所有字符,相當于取反操作 |
| A|B | 匹配表達式A或B,相當于OR操作 |
| (...) | 表達式分組,每對括號為一組,如([a-b]+)([A-Z]+)([1-9]+) |
| \number | 匹配在number表達式組內的文本 |
有一組特殊的字符序列,用來匹配具體的字符類型或字符環境。如\b匹配字符邊界,food\b匹配"food"、"zoofood",而和"foodies"不匹配。
**Table 10.4\. 特殊字符序列**
| 字符 | 描述 |
| --- | --- |
| \A | 只匹配字符串的開始 |
| \b | 匹配一個單詞邊界 |
| \B | 匹配一個單詞的非邊界 |
| \d | 匹配任意十進制數字字符,等價于r'[0-9]' |
| \D | 匹配任意非十進制數字字符,等價于r'[^0-9]' |
| \s | 匹配任意空格字符(空格符、tab制表符、換行符、回車、換頁符、垂直線符號) |
| \S | 匹配任意非空格字符 |
| \w | 匹配任意字母數字字符 |
| \W | 匹配任意非字母數字字符 |
| \Z | 僅匹配字符串的尾部 |
| \\ | 匹配反斜線字符 |
有一套聲明(assertion)對具體事件進行聲明。
**Table 10.5\. 正則表達式聲明**
| 聲明 | 描述 |
| --- | --- |
| ( iLmsux) | 匹配空字符串,iLmsux字符對應下表的正則表達式修飾符。 |
| ( :...) | 匹配圓括號內定義的表達式,但不填充字符組表。 |
| ( P<name>) | 匹配圓括號內定義的表達式,但匹配的表達式還可用作name標識的符號組。 |
| ( P=name) | 匹配所有與前面命名的字符組相匹配的文本。 |
| ( #...) | 引入注釋,忽略圓括號內的內容。 |
| ( =...) | 如果所提供的文本與下一個正則表達式元素匹配,這之間沒有多余的文本就匹配。這允許在一個表達式中進行超前操作,而不影響正則表達式其余部分的分析。如"Martin"其后緊跟"Brown",則"Martin( =Brown)"就只與"Martin"匹配。 |
| ( !...) | 僅當指定表達式與下一個正則表達式元素不匹配時匹配,是( =...)的反操作。 |
| ( <=...) | 如果字符串當前位置的前綴字符串是給定文本,就匹配,整個表達式就在當前位置終止。如( <=abc)def表達式與"abcdef"匹配。這種匹配是對前綴字符數量的精確匹配。 |
| ( <!...) | 如果字符串當前位置的前綴字符串不是給定的正文,就匹配,是( <=...)的反操作。 |
正則表達式還支持一些處理標志,它會影響正則式的執行方法。
**Table 10.6\. 處理標志**
| 標志 | 描述 |
| --- | --- |
| I或IGNORECASE | 忽略表達式的大小寫來匹配文本。 |
## 10.2\. 操作
通過re模塊,我們就可在python中利用正則式對字符串進行搜索、抽取和替換操作。如:re.search()函數能執行一個基本的搜索操作,它能返回一個MatchObject對象。re.findall()函數能返回匹配列表。
```
>>> import re
>>> a="this is my re module test"
>>> obj = re.search(r'.*is',a)
>>> print obj
<_sre.SRE_Match object at 0xb7d7a218>
>>> obj.group()
'this is'
>>> re.findall(r'.*is',a)
['this is']
```
MatchObject對象方法
**Table 10.7\. MatchObject對象方法**
| 方法 | 描述 |
| --- | --- |
| expand(template) | 展開模板中用反斜線定義的內容。 |
| m.group([group,...]) | 返回匹配的文本,是個元組。此文本是與給定group或由其索引數字定義的組匹配的文本,如果沒有組定組名,則返回所有匹配項。 |
| m.groups([default]) | 返回一個元組,該元組包含模式中與所有組匹配的文本。如果給出default參數,default參數值就是與給定表達式不匹配的組的返回值。default參數的默認取值為None。 |
| m.groupdict([default]) | 返回一個字典,該字典包含匹配的所有子組。如果給出default參數,其值就是那些不匹配組的返回值。default參數的默認取值為None。 |
| m.start([group]) | 返回指定group的開始位置,或返回全部匹配的開始位置。 |
| m.end([group]) | 返回指定group的結束位置,或返回全部匹配的結束位置。 |
| m.span([group]) | 返回兩元素組,此元組等價于關于一給定組或一個完整匹配表達式的(m.start(group),m.end(group)))列表 |
| m.pos | 傳遞給match()或search()函數的pos值。 |
| m.endpos | 傳遞給match()或search()函數的endpos值。 |
| m.lastindex |
| m.lastgroup |
| m.re | 創建這個MatchObject對象的正則式對象 |
| m.string | 提供給match()或search()函數的字符串。 |
使用sub()或subn()函數可在字符串上執行替換操作。sub()函數的基本格式如下:
```
sub(pattern,replace,string[,count])
```
示例
```
>>> str = 'The dog on my bed'
>>> rep = re.sub('dog','cat',str)
>>> print rep
The cat on my bed
```
replace參數可接受函數。要獲得替換的次數,可使用subn()函數。subn()函數返回一個元組,此元組包含替換了的文本和替換的次數。
如果需用同一個正則式進行多次匹配操作,我們可把正則式編譯成內部語言,提高處理速度。編譯正則式用compile()函數來實現。compile()函數的基本格式如下:
```
compile(str[,flags])
```
str表示需編譯的正則式串,flags是修飾標志符。正則式被編譯后生成一個對象,該對象有多種方法和屬性。
**Table 10.8\. 正則式對象方法/屬性**
| 方法/屬性 | 描述 |
| --- | --- |
| r.search(string[,pos[,endpos]]) | 同search()函數,但此函數允許指定搜索的起點和終點 |
| r.match(string[,pos[,endpos]]) | 同match()函數,但此函數允許指定搜索的起點和終點 |
| r.split(string[,max]) | 同split()函數 |
| r.findall(string) | 同findall()函數 |
| r.sub(replace,string[,count]) | 同sub()函數 |
| r.subn(replace,string[,count]) | 同subn()函數 |
| r.flags | 創建對象時定義的標志 |
| r.groupindex | 將r'( Pid)'定義的符號組名字映射為組序號的字典 |
| r.pattern | 在創建對象時使用的模式 |
轉義字符串用re.escape()函數。
通過getattr獲取對象引用
```
>>> li=['a','b']
>>> getattr(li,'append')
>>> getattr(li,'append')('c') #相當于li.append('c')
>>> li
['a', 'b', 'c']
>>> handler=getattr(li,'append',None)
>>> handler
<built-in method append of list object at 0xb7d4a52c>
>>> handler('cc') #相當于li.append('cc')
>>> li
['a','b','c','cc']
>>>result = handler('bb')
>>>li
['a','b','c','cc','bb']
>>>print result
None
```
## Chapter 11\. 調試
Python自帶了一個調試器叫pdb,和Gnu的gbd類似。下面用一個簡單的程序來演示pdb的功能。程序代碼如下:
```
#!/usr/bin/python
import pdb
a = "aaa"
pdb.set_trace()
b = "bbb"
c = "ccc"
final = a + b + c
print final
```
該程序已導入pdb模塊,并在代碼中添加的pdb.set_trace()跟蹤點。現在讓我們來運行該程序。
```
localhost:~/python/pdb# python pdbtest.py
--Return--
> /usr/lib/python2.3/pdb.py(992)set_trace()->None
-> Pdb().set_trace() # 從跟蹤點開始執行
(Pdb) n # n 讀入下一行代碼
> /root/python/pdb/pdbtest.py(6) ()
-> b = "bbb"
(Pdb) n
> /root/python/pdb/pdbtest.py(7) ()
-> c = "ccc"
(Pdb) p b # p 打印變量值
'bbb'
(Pdb) l # l 顯示當前執行位置
2
3 import pdb
4 a = "aaa"
5 pdb.set_trace()
6 b = "bbb"
7 -> c = "ccc"
8 final = a + b + c
9 print final
10
[EOF]
(Pdb) n
> /root/python/pdb/pdbtest.py(8) ()
-> final = a + b + c
(Pdb) n # 如果命令和上次的一樣,也可直接按回車,不用輸入'n'
> /root/python/pdb/pdbtest.py(9) ()
-> print final
(Pdb) n
aaabbbccc
--Return--
> /root/python/pdb/pdbtest.py(9) ()->None
-> print final
(Pdb) p a,b,c,final
('aaa', 'bbb', 'ccc', 'aaabbbccc')
(Pdb)
('aaa', 'bbb', 'ccc', 'aaabbbccc')
(Pdb) n
localhost:~/python/pdb# # 返回shell
```
pdb還有很多命令,用help命令就可以列出所有的pdb命令,用help p可以查詢p命令的說明。
## Chapter 12\. HOW-TO
本章內容記錄Python的一些小技巧小知識。來源是網上摘錄或自己學習所得。
* 如何判斷操作系統類型
```
import sys
print sys.platform
print sys.version
```
* 顯示和修改python的Module搜索路徑
```
>>> import sys
>>> print sys.path
['', '/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/local/lib/python2.3/site-packages',
'/usr/lib/python2.3/site-packages']
>>> sys.path.append('/usr/lib/mypath')
>>> print sys.path
['', '/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/local/lib/python2.3/site-packages',
'/usr/lib/python2.3/site-packages', '/usr/lib/mypath']
```
* 把列表轉換成字符串
```
>>> t=['a','b','c']
>>> print t
['a', 'b', 'c']
>>> import string
>>> print string.join(t)
a b c
```
* 運行系統程序
```
>>>import os
>>>os.system('ls') #用os.system()可執行系統命令
>>>exec "os.system('ls')" #用exec可執行字符串中的命令,兩個命令的效果一樣。
```
以上兩個命令的輸出都是直接顯示在屏幕上,不能保存到變量中,如果我們要把輸出保存起來,可用os.pope\ n()函數。
```
>>>cmd = '/usr/bin/mkntpwd %s' % password
>>>handler = os.popen(cmd,'r')
>>>passwordString=handler.read() #passwordString為mkntpwd程序的輸出結果
```
使用commands模塊也可以獲取程序的輸出,它包含一些基于os.popen()的封裝函數,使我們能更方便地獲取運行系統命令和獲取命令的輸出,但該模塊只在Unix系統下有效,不能用于Windows平臺。
```
>>> import commands
>>> status,output = commands.getstatusoutput('ls -l')
>>> print output
總計 96564
-rw-r--r-- 1 root root 4459 2005-12-01 10:23 2005.sxw
-rw-r--r-- 1 root root 27511 2006-04-12 16:54 20060412_user.ods
-rw-r--r-- 1 root root 202258 2006-01-06 16:48 2006風景-1月.jpg
...
>>> print status
0
```
在Python2.4中引入一個新的模塊叫subprocess,用于取代os.system、os.spawn\*、os.popen\*、popen2.\*、commands.\*。
* 編碼轉換
```
#!/usr/bin/python
#-*-coding:utf-8 -*-
a=u"測試"
b=a.encode('gb2312')
print a
print b
```
* 交換兩個變量
```
>>> a,b = 1,2
>>> a,b
(1, 2)
>>> a,b = b,a
>>> a,b
(2, 1)
>>> a
2
>>> b
1
```
* 測試數據類型
```
>>> a=123
>>> b='test'
>>> a
123
>>> b
'test'
>>> isinstance(a,int)
True
>>> isinstance(a,str)
False
>>> isinstance(b,int)
False
>>> isinstance(b,str)
True
```
* 用in判斷是否包含子字符串
```
>>> a='this is my test'
>>> 'is' in a
True
>>> 'mm' in a
False
```
* \_\_iter\_\_迭代器
```
>>> a = "iterator"
>>> t = iter(a)
>>> t.next()
'i'
>>> t.next()
't'
>>> t.next()
'e'
>>> t.next()
'r'
>>> t.next()
'a'
>>> t.next()
't'
>>> t.next()
'o'
>>> t.next()
'r'
>>> t.next()
Traceback (most recent call last):
File "<stdin>", line 1, in
StopIteration
```
自已寫一個迭代器類
```
>>> class reverse:
... def __init__(self,data):
... self.data=data
... self.index=len(data)
... def __iter__(self):
... return self
... def next(self):
... if self.index == 0:
... raise StopIteration
... self.index = self.index - 1
... return self.data[self.index]
...
>>> for char in reverse('iterator'):
... print char
...
r
o
t
a
r
e
t
i
>>>
```
* 通過getattr可以得到一個在運行時才知道具體函數名的對象的引用,能增強我們程序的靈活性。
```
>>> li=['a','b']
>>> getattr(li,'append')
>>> getattr(li,'append')('c') #相當于li.append('c')
>>> li
['a', 'b', 'c']
>>> handler=getattr(li,'append',None)
>>> handler
<built-in method append of list object at 0xb7d4a52c>
>>> handler('cc') #相當于li.append('cc')
>>> li
['a','b','c','cc']
>>>result = handler('bb')
>>>li
['a','b','c','cc','bb']
>>>print result
None
```
編程示例:
```
import statsout
def output(data, format="text"):
output_function = getattr(statsout, "output_%s" % format)
return output_function(data)
```
以上代碼表示,output函數接收一個data參數和format參數,根據format參數的值,從statsout模塊中取出output_text函數運行,data參數通過output_function(data)傳遞給了statsout模塊中的output_text函數。format取不同值可從statsout模塊中取出不同的函數運行(output_xxxx)。也就是說我們要運行的函數是在程序運行后才確定的。這樣我們可把不同的函數以output_xxx形式命名放在statout模塊中,通過以上程序可動態調用各種函數。
* hasattr用于確定一個對象是否具有某個屬性。
語法:
```
hasattr(object, name) -> bool
```
判斷object中是否有name屬性,返回一個布爾值。
* 拆分序列
```
>>> a=[c for c in 'abcdefg']
>>> a
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>>
```
按if條件拆分序列
```
>>> a=[c for c in '123456' if int(c)<3] 如果if的條件為真,則執行for循環
>>> a
['1', '2']
>>> a=[c for c in '123456' if int(c)>3] 如果if的條件為假,則不執行for循環
>>> a
['4', '5', '6']
```
* \_\_dict\_\_記錄模塊或類中所有對象的信息,它以字典{name:object}的形式記錄這些信息,如果wikiaction是一個模塊,則可以這樣顯示:
```
>>>import wikiaction
>>>print wikiaction.__dict__
{'do_test': <function do_test at 0xb7c10534>, 'do_diff': <function do_diff at 0xb7c0ef0c>, 'do_refresh': <fun
ction do_refresh at 0xb7c1025c>, 'do_userform': <function do_userform at 0xb7c103e4>, 'getHandler': <function
getHandler at 0xb7c105a4>, 'do_raw': <function do_raw at 0xb7c10454>, 'do_chart': <function do_chart at 0xb7
c104c4>, 're': <module 're' from '/usr/lib/python2.3/re.pyc'>, 'pysupport': <module 'MoinMoin.util.pysupport'
from '/usr/lib/python2.3/site-packages/MoinMoin/util/pysupport.pyc'>, 'config': <module 'MoinMoin.config' fr
om '/usr/lib/python2.3/site-packages/MoinMoin/config.pyc'>}
```
* 'and'的特殊用法
```
>>> 'a' and 'b' #如果兩個都為真值,返回最后一個真值
'b'
>>> 'b' and 'a' #同上
'a'
>>> 'a' and 'b' and 'c' #同上
'c'
>>> '' and 'a' #如果有假值,則返回假值
''
>>> 'a' and '' and 'c' #同上
''
>>> '' and 0 #如果兩個都為假值,返回第一個假值
''
>>> 0 and '' #同上
0
```
* 'or'的的特殊用法
```
>>> 'a' or 'b' #如果有一個為真值,則返回第一個真值
'a'
>>> 'b' or 'a' #同上
'b'
>>> 'a' or 'b' or '' #同上
'a'
>>> 0 and '' and {} #如果所有都是假值,則返回第一個假值
0
>>> {} and '' and {} #同上
{}
```
* lambda匿名函數的用法
```
>>> a=lambda c:c*2
>>> a
<function <lambda> at 0xb7dd710c>
>>> a(2)
4
>>> a(5)
10
```