Python系列教材第一集


 

 

 

 

 

 

Python 新員工教材

 

 

楚廣明2012

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

借用了一些閆小勇\鄭納智同志的文檔,向同志們致敬!

 

 

目錄

一、         Python概述. 5

1)             第一個Python程序. 6

1.             為什么要學習Python 7

2.             代碼塊與縮進的差異. 8

3.             語句結尾的差異. 8

4.             注釋方法. 8

5.             入口方法. 8

6.             import與using語句. 8

2)             小結. 9

二、         基本數據類型. 9

1)             第一個程序的解析. 9

2)             變量的命名規范. 11

3)             空類型. 11

4)             布爾類型. 11

5)             數值類型. 12

6)             字符串類型. 12

7)             全局變量. 14

三、         基本數據類型-列表(list【】) 14

四、         基本數據類型-字典(dict{}) 16

五、         基本數據類型-元組(tuple()) 18

六、         基本數據類型-集合(set) 20

七、         運算符、表達式和流程控制. 21

1)             算術運算符與算術表達式. 21

2)             賦值運算符與賦值表達式. 22

3)             關系運算符與關系表達式. 22

八、         流程控制. 23

1)             條件語句. 23

2)             循環. 23

九、         異常. 25

十、         動態表達式. 25

十一、              函數及函數編程. 26

1)             函數的定義. 26

2)             定義一個交換函數. 27

3)             函數的默認參數與返回值. 27

4)             返回多個值. 28

5)             locals函數和globals函數介紹. 28

十二、              類及面向對象. 29

1)             類的定義. 29

2)             為類添加數據. 29

3)             構造函數. 30

4)             靜態成員與私有成員. 30

5)             為類添加方法. 31

6)             靜態方法. 32

7)             單繼承. 32

十三、              模塊與包. 33

1)             對於模塊的理解. 34

2)             模塊的顯要特性:屬性. 34

3)             模塊創建過程的例子. 35

4)             模塊的導入. 35

5)             模塊的屬性. 36

十四、              字符串與簡單的正則表達式. 36

1)             解決中文字符的問題. 37

2)             字符串的格式化. 38

3)             字符串的合並與分割. 39

十五、              文件IO 41

1)             基本文件功能演示. 41

2)             文件的寫入. 43

3)             文件的刪除與復制. 44

4)             文件與目錄的重命名. 44

5)             文件內容的查找和替換. 45

6)             文件的比較. 46

十六、              Web.Py框架概述. 46

1)             Python下web開發框架的選擇. 46

1.             Django 46

2.             Pylons & TurboGears & repoze.bfg 48

3.             Tornado & web.py 48

4.             Bottle & Flask 49

5.             Quixote 50

6.             其它(web2py、uliweb、Karrigell、Werkzeug …). 50

7.             最后關於框架選擇的誤區. 50

2)             web.py安裝. 50

3)             web.py下常用框架簡介. 51

4)             最簡單的HelloWorld! 51

5)             Web.py基本使用模板使用. 51

6)             進階模板使用. 53

1.             server2.py 53

2.             post.html 53

7)             URL控制. 54

1.             問題: 54

2.             解決: 54

3.             路徑匹配. 54

8)             一個完整的小例子. 54

9)             web.seeother 和 web.redirect轉向. 55

1.             問題. 55

2.     解法. 55

3.     區別. 55

10)           包含應用. 56

1.             實現. 56

11)           使用XML 56

1.             問題. 56

2.             解法. 57

12)           獲取POST數據. 57

1.             login.html模板. 58

2.             主程序. 58

13)           獲取客戶端信息. 59

1.             問題. 59

2.             解法. 59

3.             例子. 59

4.             'ctx'中的數據成員. 59

14)           文件上傳. 60

1.             簡單的文件上傳. 60

2.             基於新浪雲的上傳. 61

十七、              Web.py使用Session 62

1)             問題. 62

2)             解法. 62

3)             在template下使用Session 64

1.             問題: 64

2.             解決: 64

4)             如何操作Cookies 65

1.             問題. 65

2.             解法. 65

3.             設置Cookies 65

4.             獲得Cookies 66

5)             布局模板. 67

1.             問題. 67

2.             方法. 67

3.             Tip: 在布局文件(layout.html)中定義的頁面標題變量. 68

4.             Tip: 在其他模板中引用css文件,如下: 68

十八、              Web.py支持的語法模板. 69

1)             使用Templetor模板語法. 69

1.             Introduction 69

2.             使用模板系統. 69

3.             表達式用法. 70

4.             賦值. 71

5.             過濾. 72

6.             新起一行用法. 72

7.             轉義 $ 72

8.             注釋. 72

9.             控制結構. 72

10.           使用 def 73

11.           使用 var 74

12.           內置 和 全局. 74

2)             使用Jinja2模板語法. 76

1.             上手的一個小例子. 76

十九、              Web.py中使用數據庫. 77

1)             使用web.py自帶的DB封裝庫. 77

1.             一個簡單的數據庫訪問測試. 77

2.             一個復雜一點的例子. 77

3.             更加復雜的例子. 78

二十、              使用Sqlalchemy 80

1)             簡介. 80

2)             初始化Sqlite數據庫. 82

3)             插入數據庫. 83

4)             在視圖中使用sqlalchemy 86

1.             首先創建數據庫models.py 86

2.             使用app.py 87

二十一、         Json的使用. 88

二十二、         Urllib模塊. 89

二十三、         SQlite模塊. 90

1)             簡單的介紹. 90

2)             安裝與使用. 90

3)             一個簡單的例子. 92

4)             中文處理. 94

 

 

 

 

 

 

 

 

 

 

一、      Python概述

Python是一門優雅而健壯的編程語言,它繼承了傳統編譯語言的強大性與通用性,同時也借鑒了簡單的腳本和解釋語言的易用性。它可以幫你完成工作,而且一段時間之后,你還能看明白自己寫的這段代碼。你會對自己如此快地學會它和它強大的功能感到十分的驚訝,更不用提你已經完成了工作了,只有你想不到,沒有Python做不到的。

就算你的項目中有大量的Python代碼,你也依舊可以有條不紊地通過將其分離為多個文件或模塊加以組織管理。而且你可以從一個模塊中選取代碼,而從另一個模塊中讀取屬性。更棒的是,對於所有模塊,Python的訪問語法都是相同的。不管這個模塊是Python標准庫中的還是你一分鍾前創建的,哪怕是你用其他語言寫的擴展都沒有問題!借助這些特點,你會自已根據需要擴展了這門語言,而且你也這么做了。

代碼中的瓶頸可能是在性能分析中總排在前面的那些熱門或者一些特別強調性能的地方,可以作為Python擴展用C重寫。需要重申的是,這些接口和純Python模塊的接口是一模一樣的,乃至代碼和對象的訪問方法也如出一轍的,唯一不同的是,這些代碼為性能帶來了顯著的提升,我們可以利用PyRex這樣的工具允計C和Python混合編程,使編寫擴展輕而易舉,因為它會把所有的代碼都轉換成C語言代碼。

因為Python的標准實現是使用C語言完成的(也就是CPython),所以要使用C和C++編寫Python擴展。Python的java實現被稱為Jython,要使用java編寫其擴展。最后還有IronPython這是針對.net平台的實現。

在各種不同的系統上你都可以看到Python的身影,因為Python是用C寫的,又由於C的可移植性,使得Python可以運行在任何帶有ANSI C編譯平台上。

l  內置的數據類型

Python提供了一些內置的數據結構,這些數據結構實現了類似Java中集合類的功能,Python的數據結構包括元組、列表、字典等 。內置的數據結構簡化了程序的設計。元組相當於“只讀”的數組,列表可以作為可變長度的數組使用,字典相當於java中的HashTable類型。

l  健壯性

Python提供了異常處理機制,能捕獲程序的異常情況。此外,Python的堆棧跟蹤對象能夠指出程序出錯的位置和出錯的原因。異常機制能夠避免不安全退出的情況,同時能幫助程序員調試程序。

l  跨平台性

Python會先編譯與平台相關的二進制代碼,然后再解釋執行,這種方式和Java相似。Python可以運行在Windows/Linux/MAC/Unix上

l  可擴展性

Python是采用C開發的語言,因此可以使用C擴展Python,可以給Python添加新的模塊、新的類。

l  動態性

Python與Javascript、PHP、Perl等語言類似。Python不需要聲明變量,直接賦予值可創建一個新的變量。

l  強類型語言

Python的變量創建后會對應一種數據類型,Python會根據賦值表達式的內容決定變量的數據類型。Python在內部建立了管理這些變量的機制,出現在同一個表達式中的不同類型的變量需要做類型轉換。

l  應用廣泛

Python語言應用於數據庫、網絡、圖形圖像、數學計算、WEB開發、操作系統擴展等領域。Python有許多第三方庫的支持。例如,PIL庫用於圖像處理、NumPy庫用於數據計算、WxPython用於GUI庫的設計、Django庫用於WEB應用程序的開發等

 

1)    第一個Python程序

在Python的官方網站可以下載到Windows下的安裝包,按照提示一路下去就可以了,記得要將Python所在的目錄加入到系統Path變量中。

Python的安裝包自帶了一個簡單的集成開發環境IDIE,你也可以選一個自己喜歡的IDE,我個人推薦PythonWin,它的語法提示功能不錯,適合初學者使用。

現在你可以打開IDIE新建一個py為擴展名的Python腳本文件,輸入以下內容:

 

保存並運行它,如果輸出>>>Hello ,World!,這說明你已經成功編寫了第一個Python程序,恭喜你!為了比較Python與Java編碼風格等方面的差異,下邊給出一個稍微復雜些的”Hello world”程序以及它的Java對照版本。

 

請注意第一行代碼是為了支持中文,沒有這一行代碼的話,我們在下面如果輸出中文就會出錯的。

 

Java的實現

/**

 * @author ChuguangMing

 *

 */

public class myfirstjava

{

  public static void main(String[] args)

  {

     System.out.println("這是Java的第一個程序");

  }

}

Python的實現

#-*-coding:utf-8-*-

"""

我的第一個應用程序

"""

import sys

def Main():

    sys.stdout.write("Hello World我的第一個程序\n")

#下面的語句看起來比較奇怪,一會兒我們會解析它

if __name__=="__main__":

Main()

 

1.  為什么要學習Python

我學習過很多語言,C#、Java、C/C++、PHP,但是效高即高而且簡單易懂的也就數Python了,可以說它是一種膠水語言,我們可以通過它將許多語言整合在一起使用。

我們來看一段代碼:

#-*-coding:utf-8-*-

"""

my fist App

"""

import sys

import urllib

def Main():

    htmlresult=urllib.urlopen("http://www.baidu.com").read()

    print htmlresult

#this is test

if __name__=="__main__":

    Main()

2.  代碼塊與縮進的差異

Java使用C/C++風格的編碼形式,除了要求用{}組織代碼塊外,語句間的縮進可以是任意的。

Python強制所有程序都有相同的編碼風格,它通過縮進來組織代碼塊,縮進相同的語句被認為是處於同一個代碼塊中,在if/else等語句及函數定義式末尾會有一個冒號,指示代碼塊的開始。Python這種強制縮進的做法可以省去{}或者begin/end等,使程序的結構更為清晰(有的人認為恰好相反),同時也減少了無效的代碼行數。

此外需要注意,盡量使用4個空格作為Python代碼的一個縮進單位,最好不要使有TAB,更不要混用Tab和空格,這也算是Python的一個非強制性約定吧。

3.  語句結尾的差異

Java用分號結尾,Python不用任何符號(類似BASIC)。實際上Python也可以使用分號結尾,像這樣a=1;b=2;c=3;print a,b,c不過Python中這種風格多用於調試,應為你可以很容易注釋掉這一行就刪除了所有的調試代碼。

另外,當一行很長時,Python可以用\符號折行顯示代碼。

4.  注釋方法

java//用單行注釋,用/**/進行多行注釋,而Python用#符號進行單行注釋,用三引號(可單可雙)進行多行注釋。

java的條件表達式必須要加括號,而Python的條件表達式加不加括號均可。

5.  入口方法

java語言必須要有入口方法Main(),這是程序開始執行的地方。Python語言中沒有入口方法(函數),作為解釋型的語言,Python代碼會自動從頭執行。

如果你對這點不習慣,可以使用Python代碼的內置屬性__name__此屬性會根據Python代碼的運行條件變化:當Python代碼以單個文件運行時,__name__便等於__main__,當你以模塊形式導入使用Python代碼時,__name__屬性便是這個模塊的名字。

當然,Python中的__name__屬於並不是為了照顧C/C++/C#程序員的編程習慣而准備的,它主要目的是用於模塊測試。想像一下在C#中編寫一個組件或類代碼時,一般還得同時編寫一個調用程序來測試它。而Python中可以把二者合二為一,這就是__name__屬性的真正作用。

6.  import與using語句

在用Python寫代碼時,我們首先import sys,這是導入了Python的sys模塊,然后在代碼里我們可以引用sys模塊中的對象stdout及它的write方法。在Python中這是必須的,否則你無法調用sys模塊中的任何東西。

簡單的說,Python中的import相當於java中的包引用。最后import可以出現在代碼的任何位置,只要在引用它之前出現就可以了,不過為了提高程序可讀性,建議還是在所有代碼開頭書寫import

2)    小結

1、 Python使用強制縮進的編碼風格,並以此組織代碼塊

2、 Python語句結尾不用分號

3、 Python標明注釋用#(單行)或三引號(多行)

4、 Python語言沒有入口方法(Main),代碼會從頭到尾順序執行

5、 Python用import引用所需要的模塊

二、      基本數據類型

1)    第一個程序的解析

“一切數據是對象,一切命名是引用”

如果你能理解這句話,說明對Python的變量與數據類型已經有了不錯的認識,與Java不同,Python在使用變量之前無須定義它的類型,試着運行下面的例子:

#-*-coding:utf-8-*-

"""

我的第一個應用程序

"""

import sys

def Main():

    sys.stdout.write("開始程序")

    i=1

    print i

#下面的語句看起來比較奇怪,一會兒我們會解析它

if __name__=="__main__":

    Main()

從上邊我們可以看到,變量i在使用前並不需要定義,但是必須聲明以及初始化該變量。試着運行下面的例子:

i=1

print i+j

上面的代碼會產生一個異常:”NameError:name ‘h’ is not defined”,Python提示變量j沒有定義。這點和BASIC等弱類型的語言不一樣。

另一方面,Python與java有一個很大的差異就是在程序運行過程中,同一變量名可以(在不同階段)代表不同類型的數據,看看下面的例子:

 

 

#-*-coding:utf-8-*-

"""

我的第一個應用程序

"""

import sys

def Main():

    sys.stdout.write("開始程序\n")

    i=1

    print i,type(i),id(i)

    i=1000000000

    print i,type(i),id(i)

    i=1.1

    print i,type(i),id(i)

#下面的語句看起來比較奇怪,一會兒我們會解析它

if __name__=="__main__":

    Main()

變量i的類型在程序執行過程中分別經歷了int long float的變化,這和靜態類型語言如C語言有很大不同。靜態語言只要有一個變量獲取了一個數據類型,它就會一直是這個類型,變量名代表的是用來存放數據的內存位置。而Python中使用的變量名只是各種數據及對象的引用,用id()獲取的才是存放數據的內存位置,我們輸入的1、1000000000、1.1三個數據均會保存在id()所指示的這些內存位置中,直到垃圾回收把它們拉走,這是動態語言的典型特征,它確定一個變量的類型是在給它賦值的時候。

另一方面,Python又是強類型的,試着運行下邊的例子:

#-*-coding:utf-8-*-

"""

我的第一個應用程序

"""

import sys

def Main():

    sys.stdout.write("開始程序\n")

    i=10

    j='虎虎'

    print i+j

#下面的語句看起來比較奇怪,一會兒我們會解析它

if __name__=="__main__":

    Main()

這個程序會出錯,產生一個異常”TypeError:unsupported operand type(s) for +:’int’ and ‘str’”。一個正確的寫法是:

#-*-coding:utf-8-*-

"""

我的第一個應用程序

"""

import sys

def Main():

    sys.stdout.write("開始程序\n")

    i=10

    j='虎虎'

    print str(i)+j

#下面的語句看起來比較奇怪,一會兒我們會解析它

if __name__=="__main__":

    Main()

所以,我們說Python即是一種動態類型語言,同時也是一種強類型的語言,這點是和java不同的地方,對於Python的這種變量的聲明、定義、使用方式。Java程序員可能要花一段時間去適應,不過相信你會很快喜歡上它,因為它讓事情變的更加簡單(而且不會不安全)。

我們再小試牛刀一下,比如我們想看看c盤下面有什么數據與目錄的話:

#-*-coding:utf-8-*-

import sys

import os

def main():

    sys.stdout.write("Hello World我的第一個程序\n")

    print os.listdir("c:/")

if __name__=="__main__":

    main()

 

2)    變量的命名規范

Python與java的變量(函數、類等其他標識符)的命名規范基本一樣,同樣對大小這與敏感。不一樣的地方是Python中以下划線開始或者結束的標識符通常有特殊的意義。例如以一個下划線開始的標識符如_foo不能用from module import *語句導入。前名均有兩個下划線的標識符,如__init__被特殊方法保留。前邊有兩個下划線的標識符,如__bar,被用來實現類私有屬性,這個將在“類和面對對象編程”中再說。

最后,Python的關鍵字不能作為標識符,不過Python的關鍵字比java要少得多,可以google一下,這里就列出了。

Python沒有常量,如果你非要定義常量,可以引用const模塊

Python程序中一切數據都是對象,包括自定義對象及基本數據類型,這一點和C#一樣,它們都是完全面向對象的語言,所以我想C#程序員很容易理解Python的一切數據都是對象這個口號。

Python不區分值類型和引用類型,你可以把所有的類型都理解為引用類型(當然,它們的實現方式不是一樣的,這里只是一個類比)。

Python內建的數據類型有20多種,其中有些不常用到的,有些即將合並。本文將主要介紹空類型、布爾類型、整型、浮點型和字符串、元組、列表、集合、字典等9種Python內置的數據類型。

在這里,我們將前4種稱為“簡單數據類型”,將后5種稱為“高級數據類型”,實際上Python語言本身沒有這種叫法,這樣分類是我自已設定的,主要是為了和java的相關知識對照方便,希望不要誤導大家。

3)    空類型

空類型(None)表示該值是一個空對象,比如沒有明確定義返回值的函數就是返回None。空類型沒有任何屬性,經常被用做函數中可選參數的默認值。None的布爾值為假。

Python的None和java中的可空類型Nullable<T>類似,比如java可以定義Nullable<double> i=null,與Python的空類型類似,但實現原理和用途都不一樣。

4)    布爾類型

Python中用True和False來定義真假,你可以直接用a=True或a=False來定義一個布爾型變量,但在Python2.6里,True/False以及None卻都不是關鍵字,在Python3.0里它們已經是關鍵字了,這個有點亂, 我們可以不用管它,直接使用就OK了。

注意和java不同的是,Python中True和False的首字母要大寫。

最后一點,在java中布爾類型和其他類型之間不存在標准的轉換。但是在Python中,None、任何數值類型中的0、空字符串’’,空元組(),空列表[],空字典{}都被當作False,其他對象均為True,這點和C++差不多,要提起注意,請思考一下,下面的Python代碼會輸出什么?

#-*-coding:utf-8-*-

"""

我的第一個應用程序

"""

import sys

def Main():

    sys.stdout.write("開始程序\n")

    if 0:

        print 'True'

    else:

        print 'False'

#下面的語句看起來比較奇怪,一會兒我們會解析它

if __name__=="__main__":

    Main()

5)    數值類型

Python擁有四種數值類型:整型、長整型、浮點類型以及復數類型。

整數類型(int)用來表示從-2147483648到2147483647之間的任意整數(在某些電腦系統上這個范圍可能會更大,但絕不會比這個更小);長整型(long)可以表示任意范圍的整數,實際上我們把Python的long和int理解為同一種類型就可以了,因為當一個整數超過int的范圍后,Python會自動將其升級為長整型

Python中只有64位雙精度浮點數float,與java中的double類型相同(注意在Python中浮點數類型名字是float而不是double),Python不支持32位單精度的浮點數。

除了整數和實數,Python還提供了一種特殊類型復數(complex)。復數使用一對浮點數表示,復數z的實部和虛部分分別用z.real和z.imag訪問。

在數值運算中,整數與浮點數運算的結果是浮點數,這就是所謂的“提升規則”,也就是“小”類型會被提升為“大”類型參與計算。這一點和java是一樣的,提升的順序依次為:int long float complex

作為數值類型的最后一個問題,java程序員需要注意的是,Python沒有內建的decimal類型,但可以導入decimal模塊用來完成與貨幣相關的計算。

Python中序列是由非負整數索引的對象的有序集合,它包括字符串、Unicode字符串,列表、元組、xrange對象以及緩沖區對象。

6)    字符串類型

Python擁有兩種字符串類型:標准字符串(str)是單字節字符序列,Unicode字符串(unicode)是雙字節字符序列。

在Python中定義一個標准字符串(str)可以使用單引號、雙引號、三引號,這使得Python輸入文本比java更方便。比如當Str的內容中包含雙引號時,就可以用單引號定義,反之亦然。當字符中有換行符等特殊字符時,可以直接使用三引號定義。這樣就方便了很多不用去記那些亂七八糟的轉義字符。當然Python也支持轉義字符,且含義與java基本一樣。

下面是一個例子來說明這一點

#-*-coding:utf-8-*-

"""

我的第一個應用程序

"""

import sys

def Main():

    sys.stdout.write("開始程序\n")

    str1='i am "python"\n'

    str2="i am 'Python' \r"

    str3="""

               i'm "Python",

               <a href="http://www.sina.com.cn"></a>

             """

    #你可以把html之類的東西都直接弄進來而不需要處理

    print str1,str2,str3

if __name__=="__main__":

Main()

在Python中定義一個Unicode字符串,需要在引號前面加上一個字符u,例如

#-*-coding:utf-8-*-

import sys

def Main():

    print u"我是派森"

if __name__=="__main__":

    Main()

同時注意,當使用UTF-8編碼時,非unicode字符中一個漢字的長度是3,而使用gb2312時是2,見下邊代碼:

#-*-coding:utf-8-*-

'''

test

'''

import sys

def Main():

    print u"我是派森"

    unicode =u'我'

    str='我'

    print len(unicode),len(str)

    #輸出的 1 3

if __name__=="__main__":

Main()

7)    全局變量

不加入global關鍵字的話,如果你是在函數內部定義的變量的話,在外部是無法獲取的。

#coding:utf-8

def testList():

    global list

    list=[]

    list.append("test1")

    list.append("test2")

    print list

testList()

print list

 

三、      基本數據類型-列表(list【】)

Python中列表(list)類似於java中的ArrayList,用於順序存儲結構。列表用符號[]表示,中間的元素可以是任何類型(包括列表本身,以實現多維數組),元素之間用逗號分隔。取值或賦值的時候可以像C數組一樣,按位置索引:

#-*-coding:utf-8-*-

import sys

def Main():

    array=[1,2,3]

    print array[0]

    #輸出1

    array[0]='a'

    print array

    #輸出['a',2,3]

    L=[123,'spam',1.23]

    #輸出大小

    print len(L)

    print L[0]

    print L[:-1]#不包含最后一個

    print L+[4,5,6]#重新拼接一個新的列表

if __name__=="__main__":

    Main()

從上邊的代碼中你可能發現一個有趣的事情:在Python的列表中可以混合使用不同類型的數據,像[‘a’,2,3]這樣,不過我不建議你這樣做,我覺着沒有什么好處。

另外還可以看到,列表是可變的序列,也就是說我們可以在“原地”改變列表上某個位置所存儲的對象的值。

Python中的list支持多數的操作,同時list也支持“切片”這樣的操作。切片指的是抽取序列的一部分,其形式為:list[start:end:step].其抽取規則是:從start開始,每次加上step,直到end為止。默認的step為1;當start沒有給出時,默認從list的第一個元素開始;當end=-1時表示list的最后一個元素,依次類推。一些簡單的例子見下邊代碼:

#-*-coding:utf-8-*-

import sys

def Main():

    test=['never',1,2,'yes',1,'no','maybe']

    print test[0:3]#包括test[0],不包括test[3]

    print test[0:6:2]#包括test[0],不包括test[6],而且步長為2

    print test[:-1]#包括開始,不包括最后一個

    print test[-3:]#抽取最后3個

if __name__=="__main__":

    Main()

字符串、列表、元組都支持切片操作,這個很方便,應該學會熟練使用它。

最后,list是Python中最基礎的數據結構,你可以把它當作鏈表、堆棧或隊列來使用,效率還不錯。Python中沒有固定長度數組,如果你確實很在意性能,可以改入array模塊來創建一個C風格的數組,它的效率很高,這里就不詳細介紹了。

我們還可以對其進行排序與反轉

#-*-coding:utf-8-*-

import sys

def Main():

    array=[5,2,3,1,8]

    array.sort()

    for s in array:

        print s

    array.reverse()

    for s in array:

        print s

if __name__=="__main__":

    Main()

 

Python核心數據類型的一個優秀的特性就是它們支持任意的嵌套。能夠以任意的組合對其進行嵌套。這種特性的一個直接應用就是實現矩陣,或者Python中的多維數組。一個嵌套列表的殂表能夠完成這個基本的操作。

#-*-coding:utf-8-*-

import sys

def Main():

    M=[[1,2,3],

            [4,5,6],

            [7,8,9]]

    print M[0]

    print M[1]

    print M[2]

if __name__=="__main__":

    Main()

處理序列的操作和列表的方法中,Python還包括了一個更高級的操作,稱作列表解析表達式,從而提供了一種處理像矩陣這樣結構的強大工具。列如,假設我們需要從列舉的矩陣中提取出第二列。因為矩陣是按照行進行存儲的,所以可以通過簡單的索引即可獲得行,使用列表解析可以同樣簡單地獲得列。

#-*-coding:utf-8-*-

import sys

def Main():

    M=[[1,2,3],

            [4,5,6],

            [7,8,9]]

    col2=[row[1] for row in M]

    print col2

    col3=[row[1]+1 for row in M]

    print col3

    colfilter=[row[1] for row in M if row[1]%2==0]

    print colfilter

if __name__=="__main__":

    Main()

 

四、      基本數據類型-字典(dict{})

用過java中的字典的人對Hashtable應該不會陌生,Python里的哈希表就是字典(dict)了。與set類似,字典是一種無序存儲結構,它包括關鍵字(key)和關鍵字對應的值(value)。

java程序員需要了解的就是,在Python中dict是一種內置的數據類型,定義方式為:

dictionary={key:value}#當有多個鍵值時,用逗號進行分割。

字典里的關鍵字為不可變類型,如字符串、整數、只包含不可變對象的元組,列表等不能作為關鍵字。字典中一個鍵只能與一個值關聯,對於同一個鍵,后添加的值會覆蓋之前的值。

學過數據結構的人對字典的散列查找效率應該都有認識,所以我建議在可能的情況下盡量多用字典,其它的就不多寫了。

#-*-coding:utf-8-*-

import sys

 

if __name__=="__main__":

    dict={"a":"apple","b":"banana","g":"grape","o":"orange"}

    print dict

    print dict["a"]

    dict2={1:"apple",2:"banana",3:"grape",4:"orange"}

    print dict2

    print dict2[1]

 

#-*-coding:utf-8-*-

import sys

 

if __name__=="__main__":

    #字典的添加、刪除、修改操作

    dict={"a":"apple","b":"banana","g":"grape","o":"orange"}

    dict["w"]="watermelon"

    print dict

    del(dict["a"])

    print dict

    print dict.pop("b")

    #dict.clear()

    #print dict

    #字典的遍歷

    for k in dict:

        print "dict[%s]="%k,dict[k]

 

#-*-coding:utf-8-*-

import sys

 

if __name__=="__main__":

    #字典的keys()與values()方法

    dict={"a":"apple","b":"banana","g":"grape","o":"orange"}

    #輸出key的列表

    print dict.keys()

    #輸出values的列表

    print dict.values()

 

#-*-coding:utf-8-*-

import sys

def Main():

    D={'food':'spam','quantity':4,'color':'pink'}

    print D['food']

    D['quantity']+=1

    print D

    #另外一種定義字典的方法

    D={}

    D['name']='Bob'

    D['job']='dev'

    D['age']=40

    print D

    #使用鍵值,進行排序

    D={'a':1,'b':2,'c':3}

    print D

    Ks=D.keys()

    print Ks

    Ks.sort()

    print Ks

    for key in Ks:

        print key,'=>',D[key]

    for key in sorted(D):

        print key,'=>',D[key]

    #迭代與優化

    squares=[x ** 2 for x in [1,2,3,4,5]]

    print squares

    #與以下代碼是等效的

    squares=[]

    for x in [1,2,3,4,5]:

        squares.append(x**2)

   

 

if __name__=="__main__":

    Main()

 

在訪問的時候,如果這個鍵值不存在的話,如果我們沒有做任何判斷的話,會出現錯誤,這個時候我們可以用以下代碼來進行判斷。

#-*-coding:utf-8-*-

import sys

def Main():

    D={'food':'spam','quantity':4,'color':'pink'}

    #測試不存在的鍵值

    if not D.has_key('f'):

        print '不存在這個鍵值'

    else:

        print D['f']

   

if __name__=="__main__":

    Main()

 

五、      基本數據類型-元組(tuple())

元組與列表非常相似,它用()而不是[]括起來的序列。元組比列表的速度更快,但元組是一個不可變的序列,也就是與str一樣,無法在原位改變它的值。除此之外,其他屬性與列表基本一致。

元組是Python中內置的一種數據結構。元組由不同的元素組成,每個元素可以存儲不同類型的數據,如字符串、數字甚至元組。元組是寫保護的!即元組創建后不能再做任何修改操作,元組通常代表一行數據,而元組中的元素代表不同的數據項。

元組的創建

#-*-coding:utf-8-*-

import sys

if __name__=="__main__":

    tuple_name=("apple","banana","grape","orange")

    print tuple_name[0]

 

分片輸出

#-*-coding:utf-8-*-

import sys

if __name__=="__main__":

    tuple_name=("apple","banana","grape","orange")

    print tuple_name[1]

    #牛在支持分片輸出

    print tuple_name[-1]

    print tuple_name[-2]

    print tuple_name[1:3]

    #我還可以在元組中包含自已

    print '-----------------'

    tuple=(('t1','t2'),('t3','t4'))

    print tuple[0][0]

    print tuple[1][0]

 

實現解包的功能

#-*-coding:utf-8-*-

import sys

if __name__=="__main__":

    tuple_name=("apple","banana","grape","orange")

    a,b,c,d=tuple_name

    print a,b,c,d

 

元組定義的方法與列表類似,不過在定義只包含一個元素的元組時,注意在后邊加一個逗號,請體會以下幾句的差異:

#-*-coding:utf-8-*-

import sys

def Main():

    test=[0]               #列表可以這樣定義

    print type(test)      #輸出<type 'list'>

    test=[0,]              #也可以這樣定義

    print type(test)      #輸出<type 'list'>

    test=(0,)              #元組可以這樣定義

    print type(test)      #輸出<type 'tuple'>

    test=(0)               #但不能這樣定義,Python會認為它是一個括號表達式

    print type(test)      #輸出<type 'int'>

    test=0,                #也可以省略括號,但要注意與C的逗號表達式不同

    print type(test)   #輸出<type 'tuple'>

    #還可以簡單的交換數據

    a=1

    b=2

    a,b=b,a

    print a,b

if __name__=="__main__":

    Main()

以上這類語句在Python中被廣泛應用於變量交換、函數傳值等應用,因此Python的解析器在不斷對其進行優化,現在已經具備了相當高的效率。所以以上代碼在Python2.5以后的版本中,比tmp=a;a=b;b=tmp這種常規語句更快。

l  Python是一種動態的強類型語言,在使用變量之前無須定義其類型,但是必須聲明和初始化

l  “一切命名是引用”,Python中變量名是對象的引用,同一變量名可以在程序運行的不同階段代表不同類型的數據

l  “一切數據都是對象”,Python的所有數據類型都是對象,相較java具有一致的使用方法

l  把問題想得更簡單一點,Python的數值類型可以說只有兩種:整形和浮點

l  多使用list/tuple/set/dict這幾種很pythonic的數據類型,它們分別用[]/()/([])/{}定義

六、      基本數據類型-集合(set)

Python中的set和java中的集合不是一個概念,這是翻譯的問題,Python中的集合是指無序的、不重復的元素集,類似數學中的集合概念,可對其進行交、並、差、補等邏輯運算。

常見集合的語法為:s=set([‘a’,’b’,’c’])。不過set在Python3.0中發生了較大的變化,創建一個集合的語法變成了:S={1,2,3},用花括號的方法,與后邊要提到的dict類似。

如果在set中傳入重復元素,集合會自動將其合並。這個特性非常有用,比如去除列表里大量的重復的元素,用set解決效率很高。示例如下:

#-*-coding:utf-8-*-

import sys

def Main():

    a=[133,224,2344,2243,22342,224,133,133,989]

    b=set(a)

    print b

if __name__=="__main__":

    Main()

另一個例子,找出兩個list里面相同的元素(集合求交,其它類推),代碼如下:

#-*-coding:utf-8-*-

import sys

def Main():

    a=[133,224,2344,2243,22342,224,133,133,989]

    b=set(a)

    print b

    a=["11","22","33"]

    b=["11","33"]

    c=set(a)&set(b)

    print c

if __name__=="__main__":

    Main()

想想你如果自已實現這個算法會怎么寫?然后可以找兩個大一點的列表,比比和set實現的效率,你就會有體會了,在以后的程序中多用set吧。

 

 

七、      運算符、表達式和流程控制

本章介紹Python的運算符、表達式、程序流程控制語句以及異常處理語句,在這方面,Python和java是非常類似的,我們僅需要注意它們之間的一些細微差異。另外,在本章我還會簡要介紹Python語言中的兩項有趣功能=列表內涵和動態表達式,雖然它們嚴格來說屬於函數部分的內容,不過我覺得還是放在表達式一章比較合適。

無論使用什么語言,我們編寫的大多數代碼都包含表達式。一個表達式可以分解為運算符和操作數,運算符的功能是完成某件事,它們由一些數學運算符號或者其他特定的關鍵字表示,運算符需要數據來進行運算,這樣的數據被稱為操作數。例如,2+3是一個簡單的表達式,其中+是運算符,2和3是操作數。

1)    算術運算符與算術表達式

算術運算符是程序設計語言最基本的運算符。Python提供的算術運算符除了+、-、*、/、%(求余)之外,還提供了兩種java中沒有提供的運算符:求冪(**)和取整除(//).下面我們就通過一段代碼來解析這兩個算術運算符的功能。

#-*-coding:utf-8-*-

import sys

def Main():

    x=3.3

    y=2.2

    a=x**y

    print a

    #輸出即3.3的2.2次冪

    b=x//y

    print b

    #輸出1.0取整除返回商的整數部分

    c=x/y

    print c

    #輸出1.5,注意體會普通除與取整除的區別

if __name__=="__main__":

    Main()

2)    賦值運算符與賦值表達式

賦值就是給一個變量賦一個新值,除了簡單的=賦值之外,Python和java都支持復合賦值,例如x+=5,等價於x=x+5.

Python不支持java中的自增和自減運算符,例如X++這種語句在Python中會被提示語法有錯誤。java程序員可能習慣了這種表達式,在Python中,請老老實實的寫X+=1就是了。

Python的邏輯運算符與java有較大區別,Python用關鍵字and or not 代替了java語言中的邏輯運算符 && || !,此外Python中參與邏輯運算符的操作數不限於布爾類型,任何類型的值都可以參與邏輯運算中去。

用邏輯運算符將操作數或表達式連接起來就是邏輯表達式。與java一樣,Python中邏輯表達式是短路執行的,也就是說只有需要時才會進行邏輯表達式右邊值的計算,例如表達式a and b 只有當a為true時才計算b.思考一下,if(0 and 10/0):這條語句會引發除數為零的異常嗎?

此外還要注意:在Python中,and和or所執行的邏輯運算並不返回布爾值,而是返回它們實際進行比較的值之一。下邊是一個例子:

#-*-coding:utf-8-*-

import sys

def Main():

    print 'a' and 'b'

    print '' and 'b'

if __name__=="__main__":

    Main()

 

3)    關系運算符與關系表達式

關系運算符實際上是邏輯運算的一種,關系表達式的返回值總是布爾值。Python中的比較操作符與java完全是一樣的,包括== != > < >= <=共6種。

除了基本的變量比較外,Python的關系運算符還包括身份運算符is.在Python中,is用來檢驗兩個對象在內存中是否指向同一個對象(還記得一切數據皆對象嗎?一切命名皆引用嗎)。

三元運算符

三元運算符是c/c++系語言所特有的一類運算符,例如,對表達式b?x:y,先計算條件b,然后進行判斷,如果b的值為true,則計算並返回x的值,否則計算並返回y的值。

在Python中,提供了專門的邏輯分支表達式來模擬java系中的三元運算,我們也可以在一行語句中完成三元運算,例如

print ‘偶數’ if x%2==0 else ‘奇數’

八、      流程控制

1)    條件語句

Python用if,elif,else這三個關鍵字進行條件判斷,與java唯一的區別就是用elif取代else if,少打兩個字,其它都一樣,此外別忘了在if等語句后加:號

如果一個流程控制分南下不做任何事情,記得寫一句pass語句,不然Python會報錯。例如:

if 0:

     pass #這一句語沒有什么意義

在Python中沒有switch語句,你可以使用if..elif..else語句來完成同樣的工作。如果你覺得繁瑣,可以試試dict實現的方式,下邊是一個例子,分別對比了兩種實現方式。

#-*-coding:utf-8-*-

import sys

def Main():

    #使用if替代

    x='4'

    print "OK"

    if x=='1':

        print 'one'

    elif x=='2':

        print 'two'

    else:

        print 'nothing!'

    #使用dict

    numtrans={

        1:'one',

        2:'two',

        3:'three'

    }

    try:

        print numtrans[x]

    except KeyError:

        print 'nothing!'

if __name__=="__main__":

    Main()

2)    循環

Python支持兩種循環語句while循環和for循環,不支持java中的do-while循環。在Python的while循環和Java基本一致,此處我們着重比較兩種語言中的for循環的區別。

說的簡單一點,python中的for語句相當於java中的foreach語句,它用於從集合對象(list/str/tuple等)中遍歷數據。例如:

for I in [1,2,3,4,5]:

print i

for I in range(10):

  print i

 

#-*-coding:utf-8-*-

import sys

if __name__=="__main__":

    tuple=(("apple","banana"),("grape","orange"))

    for i in range(50,100+1):

        print i

   

 

#-*-coding:utf-8-*-

import sys

if __name__=="__main__":

    for i in range(50,100+1):

        print i

    range(1,5) #代表從1到5(不包含5)

    range(1,5,2) #代表從1到5,間隔2(不包含5)

    range(5) #代表從0到5(不包含5)

 

__author__ = 'TenYear'

#-*-coding:utf-8-*-

"""

my fist App

"""

import sys

import urllib

def Main():

    itemlist=[1,2,3,4,5,4]

    for m in itemlist:

        print m

#this is test

if __name__=="__main__":

    Main()

九、      異常

Python和java一樣支持異常處理,利用try/except/finally結構,可以很方便的捕獲異常,同時可以用raise語句手動拋出異常(上述四個異常處理的關鍵字分別對就應Java中的try/catch/finally/throw).通過except,您可以將try標示的語句中出現的錯誤和異常捕獲。

#-*-coding:utf-8-*-

import sys

def Main():

    try:

        f=open('firstpython.py')

        s=f.readline()

        print s

    except IOError,(errno,strerror):

        print "I/O error(%s):%s" %(errno,strerror)

    except ValueError:

        print "Could not convert data to an integer"

    except:

        print "Unexpected error:",sys.exc_info()[0]

        raise

    finally:

        f.close()

if __name__=="__main__":

    Main()

最后說明一點,python的try也支持else語句,如果有一些代碼要在try沒有發生異常的情況下才執行,就可以把它放在else中。

十、      動態表達式

在C#語言中,如果需要在文本框中輸入1+2(或更加復雜的數學表達式)后計算它的值,可能會用到表達式解析等。現在我們有了Python,要完成這種任務可以說是非常簡單:只要用內置的eval()函數,就可以計算並返回任意有效表達式的值。例如:

str=’1+2’

print eval(str)

除了eval函數之外,Python還提供了exec語句將字符串str當成有效Python代碼來執行,看下面的例子:

exec ‘a=100’

print a

另外還有execfile函數,它用來執行一個外部的py文件,上一個例子存為exec.py后,運行下邊的代碼就知道是怎么回事了:

execfile(r’c:\exec.py’)

最后提醒,默認的eval(),exec,execfile()所運行的代碼都位於當前的名字空間中,eval(),exec,和execfile()函數也可以接受一個或兩個可選字典參數作為代碼執行的全局名字空間和局部名字空間,具體可以參考Python手冊。

列表內涵是Python最強有力的語法之一,常用於從集合對象中有選擇地獲取並計算元素,雖然多數情況下可以使用for/if等語句組合完成同樣的任務,但列表內涵書寫的代碼更加簡潔。

 

#-*-coding:utf-8-*-

import sys

def func():

    x=1

    y=2

    m=3

    n=4

    sum=lambda x,y:x+y

    print sum

    sub=lambda m,n:m-n

    print sub

    return sum(x,y)*sub(m,n)

if __name__=="__main__":

    print func()

列表內涵的一般形式如下,我們可以把[]內的列表內涵寫為一行,也可以寫為多行。

[表達式 for item1 in 序列1 … for itemN in 序列N if 條件表達式]

上面的表達式分為三部分,最左邊是生成每個元素的表達式,然后是for迭代過程,最右邊可以設定一個if判斷作為過濾條件。

列表內涵的一個著名例子是生成九九乘法表:

s=[(x,y,x*y) for x in range(1,10) for y in range(1,10) if x>=y]

十一、     函數及函數編程

在java中沒有獨立的函數存在,只有類的(動態或靜態)方法這一概念,它指的是類中用於執行計算或其它行為的成員。在Python中,你可以使用類似C#的方式定義類的動態或靜態成員方法,因為它與java一樣支持完全的面向對象編程。你也可以用過程式編程的方式來編寫Python程序,這時Python中的函數與類可以沒有任何關系,類似C語言定義和使用函數的方式。此外,Python還支持函數式編程,雖然它對函數編程的支持不如LISP等語言那樣完備,但適合使用還是可以提高我們工作的效率的。

1)    函數的定義

函數定義是最基本的行為抽象代碼,也是軟件復用最初級的方式。Python中函數的定義語句由def關鍵字、函數名、括號、參數及冒號組成。下面是幾個簡單的函數定義語句:

#-*-coding:utf-8-*-

import sys

def Main():

    def F1():

        print "我是F1"

    def F2(x,y):

        a=x+y

        return a

    #定義有多個返回值的函數,用逗號分割不同的返回值,

    #返回結果是一個元組

    def F3(x,y):

        a=x/y

        b=x%y

        return a,b

if __name__=="__main__":

    Main()

可能你已經注意到了,Python定義函數的時候並沒有約束參數的類型,它以最簡單的形式支持了泛型編程。你可以輸入任意類型的數據作為參數,只要這些類型支持函數內部的操作

2)    定義一個交換函數

 

#-*-coding:utf-8-*-

import sys

import random

def compareNum(num1,num2):

    if(num1>num2):

        return 1

    elif(num1==num2):

        return 0

    else:

        return -1

if __name__=="__main__":

    num1=random.randrange(1,9)

    num2=random.randrange(1,9)

    print "num1=",num1

    print "num2=",num2

    print compareNum(num1,num2)

3)    函數的默認參數與返回值

#-*-coding:utf-8-*-

import sys

def arithmetic(x=1,y=1,operator="+"):

    result={

        "+":x+y,

        "-":x-y,

        "*":x*y,

        "/":x/y

    }

    return result.get(operator)

if __name__=="__main__":

    print arithmetic(1,2)

    print arithmetic(1,2,"-")

4)    返回多個值

Python支持多個返回值

#coding:utf-8

def testList():

    return "aaa","bbb"

a,b=testList()

print a

print b

 

5)    locals函數和globals函數介紹

Python有兩個內置的函數,locals() 和globals(),它們提供了基於字典的訪問局部和全局變量的方式。首先,是關於名字空間的一個名詞解釋。是枯燥,但是很重要,所以要耐心些。Python使用叫做名字空間的東西來記錄變量的軌跡。名字空間只是一個字典,它的鍵字就是變量名,字典的值就是那些變量的值。實際上,名字空間可以象Python的字典一樣進行訪問,一會我們就會看到。

 

在一個Python程序中的任何一個地方,都存在幾個可用的名字空間。每個函數都有着自已的名字空間,叫做局部名字空間,它記錄了函數的變量,包括 函數的參數和局部定義的變量。每個模塊擁有它自已的名字空間,叫做全局名字空間,它記錄了模塊的變量,包括函數、類、其它導入的模塊、模塊級的變量和常量。還有就是內置名字空間,任何模塊均可訪問它,它存放着內置的函數和異常。

 

當一行代碼要使用變量 x 的值時,Python會到所有可用的名字空間去查找變量,按照如下順序:

1.局部名字空間 - 特指當前函數或類的方法。如果函數定義了一個局部變量 x,Python將使用這個變量,然后停止搜索。

2.全局名字空間 - 特指當前的模塊。如果模塊定義了一個名為 x 的變量,函數或類,Python將使用這個變量然后停止搜索。

3.內置名字空間 - 對每個模塊都是全局的。作為最后的嘗試,Python將假設 x 是內置函數或變量。

如果Python在這些名字空間找不到 x,它將放棄查找並引發一個 NameError 的異常,同時傳遞 There is no variable named 'x' 這樣一條信息,象Python中的許多事情一樣,名字空間在運行時直接可以訪問。特別地,局部名字空間可以通過內置的 locals 函數來訪問。全局(模塊級別)名字空間可以通過 globals 函數來訪問

 

#coding:utf-8

from __future__ import  unicode_literals

from sys import *

def test(arg):

    #函數test在它的局部名字空間中有兩個變量:arg(它的值被傳入函數)

    # 和z(它在函數內部)

    z=1

    print locals()

#locals返回一個名字與值的字典,這個字典的鍵字是字符串形式的變量名

#字典的值是變量的實際值

test(5)

test('楚廣明')

print globals()#返回一個全局的字典,包括所有導入的變量


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM