1. 程式人生 > >廖雪峰Python 2.X 教程

廖雪峰Python 2.X 教程

Python簡介

Python是著名的“龜叔”Guido van Rossum在1989年聖誕節期間,為了打發無聊的聖誕節而編寫的一個程式語言。

當你用一種語言開始作真正的軟體開發時,你除了編寫程式碼外,還需要很多基本的已經寫好的現成的東西,來幫助你加快開發進度。比如說,要編寫一個電子郵件客戶端,如果先從最底層開始編寫網路協議相關的程式碼,那估計一年半載也開發不出來。高階程式語言通常都會提供一個比較完善的基礎程式碼庫,讓你能直接呼叫,比如,針對電子郵件協議的SMTP庫,針對桌面環境的GUI庫,在這些已有的程式碼庫的基礎上開發,一個電子郵件客戶端幾天就能開發出來。

Python就為我們提供了非常完善的基礎程式碼庫,覆蓋了網路、檔案、GUI、資料庫、文字等大量內容,被形象地稱作“內建電池(batteries included)”。用Python開發,許多功能不必從零編寫,直接使用現成的即可。

除了內建的庫外,Python還有大量的第三方庫,也就是別人開發的,供你直接使用的東西。當然,如果你開發的程式碼通過很好的封裝,也可以作為第三方庫給別人使用。

許多大型網站就是用Python開發的,例如YouTube、Instagram,還有國內的豆瓣。很多大公司,包括Google、Yahoo等,甚至NASA(美國航空航天局)都大量地使用Python。

龜叔給Python的定位是“優雅”、“明確”、“簡單”,所以Python程式看上去總是簡單易懂,初學者學Python,不但入門容易,而且將來深入下去,可以編寫那些非常非常複雜的程式。

總的來說,Python的哲學就是簡單優雅,儘量寫容易看明白的程式碼,儘量寫少的程式碼。如果一個資深程式設計師向你炫耀他寫的晦澀難懂、動不動就幾萬行的程式碼,你可以盡情地嘲笑他。

那Python適合開發哪些型別的應用呢?

首選是網路應用,包括網站、後臺服務等等;

其次是許多日常需要的小工具,包括系統管理員需要的指令碼任務等等;

另外就是把其他語言開發的程式再包裝起來,方便使用。

最後說說Python的缺點。

任何程式語言都有缺點,Python也不例外。優點說過了,那Python有哪些缺點呢?

第一個缺點就是執行速度慢,和C程式相比非常慢,因為Python是解釋型語言,你的程式碼在執行時會一行一行地翻譯成CPU能理解的機器碼,這個翻譯過程非常耗時,所以很慢。而C程式是執行前直接編譯成CPU能執行的機器碼,所以非常快。

但是大量的應用程式不需要這麼快的執行速度,因為使用者根本感覺不出來。例如開發一個下載MP3的網路應用程式,C程式的執行時間需要0.001秒,而Python程式的執行時間需要0.1秒,慢了100倍,但由於網路更慢,需要等待1秒,你想,使用者能感覺到1.001秒和1.1秒的區別嗎?這就好比F1賽車和普通的計程車在北京三環路上行駛的道理一樣,雖然F1賽車理論時速高達400公里,但由於三環路堵車的時速只有20公里,因此,作為乘客,你感覺的時速永遠是20公里。

第二個缺點就是程式碼不能加密。如果要釋出你的Python程式,實際上就是釋出原始碼,這一點跟C語言不同,C語言不用釋出原始碼,只需要把編譯後的機器碼(也就是你在Windows上常見的xxx.exe檔案)釋出出去。要從機器碼反推出C程式碼是不可能的,所以,凡是編譯型的語言,都沒有這個問題,而解釋型的語言,則必須把原始碼釋出出去。

這個缺點僅限於你要編寫的軟體需要賣給別人掙錢的時候。好訊息是目前的網際網路時代,靠賣軟體授權的商業模式越來越少了,靠網站和移動應用賣服務的模式越來越多了,後一種模式不需要把原始碼給別人。

再說了,現在如火如荼的開源運動和網際網路自由開放的精神是一致的,網際網路上有無數非常優秀的像Linux一樣的開原始碼,我們千萬不要高估自己寫的程式碼真的有非常大的“商業價值”。那些大公司的程式碼不願意開放的更重要的原因是程式碼寫得太爛了,一旦開源,就沒人敢用他們的產品了。

當然,Python還有其他若干小缺點,請自行忽略,就不一一列舉了。

安裝Python

因為Python是跨平臺的,它可以執行在Windows、Mac和各種Linux/Unix系統上。在Windows上寫Python程式,放到Linux上也是能夠執行的。

要開始學習Python程式設計,首先就得把Python安裝到你的電腦裡。安裝後,你會得到Python直譯器(就是負責執行Python程式的),一個命令列互動環境,還有一個簡單的整合開發環境。

2.x還是3.x

目前,Python有兩個版本,一個是2.x版,一個是3.x版,這兩個版本是不相容的,因為現在Python正在朝著3.x版本進化,在進化過程中,大量的針對2.x版本的程式碼要修改後才能執行,所以,目前有許多第三方庫還暫時無法在3.x上使用。

為了保證你的程式能用到大量的第三方庫,我們的教程仍以2.x版本為基礎,確切地說,是2.7版本。請確保你的電腦上安裝的Python版本是2.7.x,這樣,你才能無痛學習這個教程。

在Mac上安裝Python

如果你正在使用Mac,系統是OS X 10.8或者最新的10.9 Mavericks,恭喜你,系統自帶了Python 2.7。如果你的系統版本低於10.8,請自行備份系統並免費升級到最新的10.9,就可以獲得Python 2.7。

檢視系統版本的辦法是點選左上角的蘋果圖示,選擇“關於本機”:

在Linux上安裝Python

如果你正在使用Linux,那我可以假定你有Linux系統管理經驗,自行安裝Python 2.7應該沒有問題,否則,請換回Windows系統。

對於大量的目前仍在使用Windows的同學,如果短期內沒有打算換Mac,就可以繼續閱讀以下內容。

在Windows上安裝Python

首先,從Python的官方網站www.python.org下載最新的2.7.9版本,地址是這個:

然後,執行下載的MSI安裝包,在選擇安裝元件的一步時,勾上所有的元件:

特別要注意選上pipAdd python.exe to Path,然後一路點“Next”即可完成安裝。

預設會安裝到C:\Python27目錄下,然後開啟命令提示符視窗,敲入python後,會出現兩種情況:

情況一:

看到上面的畫面,就說明Python安裝成功!

你看到提示符>>>就表示我們已經在Python互動式環境中了,可以輸入任何Python程式碼,回車後會立刻得到執行結果。現在,輸入exit()並回車,就可以退出Python互動式環境(直接關掉命令列視窗也可以!)。

情況二:得到一個錯誤:

‘python’不是內部或外部命令,也不是可執行的程式或批處理檔案。

這是因為Windows會根據一個Path的環境變數設定的路徑去查詢python.exe,如果沒找到,就會報錯。如果在安裝時漏掉了勾選Add python.exe to Path,那就要手動把python.exe所在的路徑C:\Python27新增到Path中。

如果你不知道怎麼修改環境變數,建議把Python安裝程式重新執行一遍,記得勾上Add python.exe to Path

小結

學會如何把Python安裝到計算機中,並且熟練開啟和退出Python互動式環境。

Python直譯器

當我們編寫Python程式碼時,我們得到的是一個包含Python程式碼的以.py為副檔名的文字檔案。要執行程式碼,就需要Python直譯器去執行.py檔案。

由於整個Python語言從規範到直譯器都是開源的,所以理論上,只要水平夠高,任何人都可以編寫Python直譯器來執行Python程式碼(當然難度很大)。事實上,確實存在多種Python直譯器。

CPython

當我們從Python官方網站下載並安裝好Python 2.7後,我們就直接獲得了一個官方版本的直譯器:CPython。這個直譯器是用C語言開發的,所以叫CPython。在命令列下執行python就是啟動CPython直譯器。

CPython是使用最廣的Python直譯器。教程的所有程式碼也都在CPython下執行。

IPython

IPython是基於CPython之上的一個互動式直譯器,也就是說,IPython只是在互動方式上有所增強,但是執行Python程式碼的功能和CPython是完全一樣的。好比很多國產瀏覽器雖然外觀不同,但核心其實都是呼叫了IE。

CPython用>>>作為提示符,而IPython用In [序號]:作為提示符。

PyPy

PyPy是另一個Python直譯器,它的目標是執行速度。PyPy採用JIT技術,對Python程式碼進行動態編譯(注意不是解釋),所以可以顯著提高Python程式碼的執行速度。

絕大部分Python程式碼都可以在PyPy下執行,但是PyPy和CPython有一些是不同的,這就導致相同的Python程式碼在兩種直譯器下執行可能會有不同的結果。如果你的程式碼要放到PyPy下執行,就需要了解PyPy和CPython的不同點

Jython

Jython是執行在Java平臺上的Python直譯器,可以直接把Python程式碼編譯成Java位元組碼執行。

IronPython

IronPython和Jython類似,只不過IronPython是執行在微軟.Net平臺上的Python直譯器,可以直接把Python程式碼編譯成.Net的位元組碼。

小結

Python的直譯器很多,但使用最廣泛的還是CPython。如果要和Java或.Net平臺互動,最好的辦法不是用Jython或IronPython,而是通過網路呼叫來互動,確保各程式之間的獨立性。

本教程的所有程式碼只確保在CPython 2.7版本下執行。請務必在本地安裝CPython(也就是從Python官方網站下載的安裝程式)。

此外,教程還內嵌一個IPython的Web版本,用來在瀏覽器內練習執行一些Python程式碼。要注意兩者功能一樣,輸入的程式碼一樣,但是提示符有所不同。另外,不是所有程式碼都能在Web版本的IPython中執行,出於安全原因,很多操作(比如檔案操作)是受限的,所以有些程式碼必須在本地環境執行程式碼。

第一個Python程式

現在,瞭解瞭如何啟動和退出Python的互動式環境,我們就可以正式開始編寫Python程式碼了。

在寫程式碼之前,請千萬不要用“複製”-“貼上”把程式碼從頁面貼上到你自己的電腦上。寫程式也講究一個感覺,你需要一個字母一個字母地把程式碼自己敲進去,在敲程式碼的過程中,初學者經常會敲錯程式碼,所以,你需要仔細地檢查、對照,才能以最快的速度掌握如何寫程式。

在互動式環境的提示符>>>下,直接輸入程式碼,按回車,就可以立刻得到程式碼執行結果。現在,試試輸入100+200,看看計算結果是不是300:

>>> 100+200
300

很簡單吧,任何有效的數學計算都可以算出來。

如果要讓Python打印出指定的文字,可以用print語句,然後把希望列印的文字用單引號或者雙引號括起來,但不能混用單引號和雙引號:

>>> print 'hello, world'
hello, world

這種用單引號或者雙引號括起來的文字在程式中叫字串,今後我們還會經常遇到。

最後,用exit()退出Python,我們的第一個Python程式完成!唯一的缺憾是沒有儲存下來,下次執行時還要再輸入一遍程式碼。

小結

在Python互動式命令列下,可以直接輸入程式碼,然後執行,並立刻得到結果。

使用文字編輯器

在Python的互動式命令列寫程式,好處是一下就能得到結果,壞處是沒法儲存,下次還想執行的時候,還得再敲一遍。

所以,實際開發的時候,我們總是使用一個文字編輯器來寫程式碼,寫完了,儲存為一個檔案,這樣,程式就可以反覆運行了。

現在,我們就把上次的'hello, world'程式用文字編輯器寫出來,儲存下來。

那麼問題來了:文字編輯器到底哪家強?

推薦兩款文字編輯器:

一個是Sublime Text,免費使用,但是不付費會彈出提示框:

一個是Notepad++,免費使用,有中文介面:

請注意,用哪個都行,但是絕對不能用Word和Windows自帶的記事本。Word儲存的不是純文字檔案,而記事本會自作聰明地在檔案開始的地方加上幾個特殊字元(UTF-8 BOM),結果會導致程式執行出現莫名其妙的錯誤。

安裝好文字編輯器後,輸入以下程式碼:

print 'hello, world'

注意print前面不要有任何空格。然後,選擇一個目錄,例如C:\Workspace,把檔案儲存為hello.py,就可以開啟命令列視窗,把當前目錄切換到hello.py所在目錄,就可以執行這個程式了:

C:\Workspace>python hello.py
hello, world

也可以儲存為別的名字,比如abc.py,但是必須要以.py結尾,其他的都不行。此外,檔名只能是英文字母、數字和下劃線的組合。

如果當前目錄下沒有hello.py這個檔案,執行python hello.py就會報錯:

python hello.py
python: can't open file 'hello.py': [Errno 2] No such file or directory

報錯的意思就是,無法開啟hello.py這個檔案,因為檔案不存在。這個時候,就要檢查一下當前目錄下是否有這個檔案了。

請注意區分命令列模式和Python互動模式:

看到類似C:\>是在Windows提供的命令列模式,看到>>>是在Python互動式環境下。

在命令列模式下,可以執行python進入Python互動式環境,也可以執行python hello.py執行一個.py檔案,但是在Python互動式環境下,只能輸入Python程式碼執行。

直接執行py檔案

還有同學問,能不能像.exe檔案那樣直接執行.py檔案呢?在Windows上是不行的,但是,在Mac和Linux上是可以的,方法是在.py檔案的第一行加上:

#!/usr/bin/env python

然後,通過命令:

$ chmod a+x hello.py

就可以直接執行hello.py了,比如在Mac下執行:

小結

用文字編輯器寫Python程式,然後儲存為字尾為.py的檔案,就可以用Python直接執行這個程式了。

Python的互動模式和直接執行.py檔案有什麼區別呢?

直接輸入python進入互動模式,相當於啟動了Python直譯器,但是等待你一行一行地輸入原始碼,每輸入一行就執行一行。

直接執行.py檔案相當於啟動了Python直譯器,然後一次性把.py檔案的原始碼給執行了,你是沒有機會輸入原始碼的。

用Python開發程式,完全可以一邊在文字編輯器裡寫程式碼,一邊開一個互動式命令視窗,在寫程式碼的過程中,把部分程式碼粘到命令列去驗證,事半功倍!前提是得有個27'的超大顯示器!

輸入和輸出

輸出

print加上字串,就可以向螢幕上輸出指定的文字。比如輸出'hello, world',用程式碼實現如下:

>>> print 'hello, world'

print語句也可以跟上多個字串,用逗號“,”隔開,就可以連成一串輸出:

>>> print 'The quick brown fox', 'jumps over', 'the lazy dog'
The quick brown fox jumps over the lazy dog

print會依次列印每個字串,遇到逗號“,”會輸出一個空格,因此,輸出的字串是這樣拼起來的:

print也可以列印整數,或者計算結果:

>>> print 300
300
>>> print 100 + 200
300

因此,我們可以把計算100 + 200的結果列印得更漂亮一點:

>>> print '100 + 200 =', 100 + 200
100 + 200 = 300

注意,對於100 + 200,Python直譯器自動計算出結果300,但是,'100 + 200 ='是字串而非數學公式,Python把它視為字串,請自行解釋上述列印結果。

輸入

現在,你已經可以用print輸出你想要的結果了。但是,如果要讓使用者從電腦輸入一些字元怎麼辦?Python提供了一個raw_input,可以讓使用者輸入字串,並存放到一個變數裡。比如輸入使用者的名字:

>>> name = raw_input()
Michael

當你輸入name = raw_input()並按下回車後,Python互動式命令列就在等待你的輸入了。這時,你可以輸入任意字元,然後按回車後完成輸入。

輸入完成後,不會有任何提示,Python互動式命令列又回到>>>狀態了。那我們剛才輸入的內容到哪去了?答案是存放到name變數裡了。可以直接輸入name檢視變數內容:

>>> name
'Michael'

什麼是變數?請回憶初中數學所學的代數基礎知識:

設正方形的邊長為a,則正方形的面積為a x a。把邊長a看做一個變數,我們就可以根據a的值計算正方形的面積,比如:

若a=2,則面積為a x a = 2 x 2 = 4;

若a=3.5,則面積為a x a = 3.5 x 3.5 = 12.25。

在計算機程式中,變數不僅可以為整數或浮點數,還可以是字串,因此,name作為一個變數就是一個字串。

要打印出name變數的內容,除了直接寫name然後按回車外,還可以用print語句:

>>> print name
Michael

有了輸入和輸出,我們就可以把上次列印'hello, world'的程式改成有點意義的程式了:

name = raw_input()
print 'hello,', name

執行上面的程式,第一行程式碼會讓使用者輸入任意字元作為自己的名字,然後存入name變數中;第二行程式碼會根據使用者的名字向用戶說hello,比如輸入Michael

C:\Workspace> python hello.py
Michael
hello, Michael

但是程式執行的時候,沒有任何提示資訊告訴使用者:“嘿,趕緊輸入你的名字”,這樣顯得很不友好。幸好,raw_input可以讓你顯示一個字串來提示使用者,於是我們把程式碼改成:

name = raw_input('please enter your name: ')
print 'hello,', name

再次執行這個程式,你會發現,程式一執行,會首先打印出please enter your name:,這樣,使用者就可以根據提示,輸入名字後,得到hello, xxx的輸出:

C:\Workspace> python hello.py
please enter your name: Michael
hello, Michael

每次執行該程式,根據使用者輸入的不同,輸出結果也會不同。

在命令列下,輸入和輸出就是這麼簡單。

小結

任何計算機程式都是為了執行一個特定的任務,有了輸入,使用者才能告訴計算機程式所需的資訊,有了輸出,程式執行後才能告訴使用者任務的結果。

輸入是Input,輸出是Output,因此,我們把輸入輸出統稱為Input/Output,或者簡寫為IO。

raw_inputprint是在命令列下面最基本的輸入和輸出,但是,使用者也可以通過其他更高階的圖形介面完成輸入和輸出,比如,在網頁上的一個文字框輸入自己的名字,點選“確定”後在網頁上看到輸出資訊。

Python基礎

Python是一種計算機程式語言。計算機程式語言和我們日常使用的自然語言有所不同,最大的區別就是,自然語言在不同的語境下有不同的理解,而計算機要根據程式語言執行任務,就必須保證程式語言寫出的程式決不能有歧義,所以,任何一種程式語言都有自己的一套語法,編譯器或者直譯器就是負責把符合語法的程式程式碼轉換成CPU能夠執行的機器碼,然後執行。Python也不例外。

Python的語法比較簡單,採用縮排方式,寫出來的程式碼就像下面的樣子:

# print absolute value of an integer:
a = 100
if a >= 0:
    print a
else:
    print -a

#開頭的語句是註釋,註釋是給人看的,可以是任意內容,直譯器會忽略掉註釋。其他每一行都是一個語句,當語句以冒號“:”結尾時,縮排的語句視為程式碼塊。

縮排有利有弊。好處是強迫你寫出格式化的程式碼,但沒有規定縮排是幾個空格還是Tab。按照約定俗成的管理,應該始終堅持使用4個空格的縮排。

縮排的另一個好處是強迫你寫出縮排較少的程式碼,你會傾向於把一段很長的程式碼拆分成若干函式,從而得到縮排較少的程式碼。

縮排的壞處就是“複製-貼上”功能失效了,這是最坑爹的地方。當你重構程式碼時,貼上過去的程式碼必須重新檢查縮排是否正確。此外,IDE很難像格式化Java程式碼那樣格式化Python程式碼。

最後,請務必注意,Python程式是大小寫敏感的,如果寫錯了大小寫,程式會報錯。

資料型別和變數

資料型別

計算機顧名思義就是可以做數學計算的機器,因此,計算機程式理所當然地可以處理各種數值。但是,計算機能處理的遠不止數值,還可以處理文字、圖形、音訊、視訊、網頁等各種各樣的資料,不同的資料,需要定義不同的資料型別。在Python中,能夠直接處理的資料型別有以下幾種:

整數

Python可以處理任意大小的整數,當然包括負整數,在程式中的表示方法和數學上的寫法一模一樣,例如:1100-80800,等等。

計算機由於使用二進位制,所以,有時候用十六進位制表示整數比較方便,十六進位制用0x字首和0-9,a-f表示,例如:0xff000xa5b4c3d2,等等。

浮點數

浮點數也就是小數,之所以稱為浮點數,是因為按照科學記數法表示時,一個浮點數的小數點位置是可變的,比如,1.23x109和12.3x108是相等的。浮點數可以用數學寫法,如1.233.14-9.01,等等。但是對於很大或很小的浮點數,就必須用科學計數法表示,把10用e替代,1.23x109就是1.23e9,或者12.3e8,0.000012可以寫成1.2e-5,等等。

整數和浮點數在計算機內部儲存的方式是不同的,整數運算永遠是精確的(除法難道也是精確的?是的!),而浮點數運算則可能會有四捨五入的誤差。

字串

字串是以''或""括起來的任意文字,比如'abc'"xyz"等等。請注意,''或""本身只是一種表示方式,不是字串的一部分,因此,字串'abc'只有abc這3個字元。如果'本身也是一個字元,那就可以用""括起來,比如"I'm OK"包含的字元是I'm,空格,OK這6個字元。

如果字串內部既包含'又包含"怎麼辦?可以用轉義字元\來標識,比如:

'I\'m \"OK\"!'

表示的字串內容是:

I'm "OK"!

轉義字元\可以轉義很多字元,比如\n表示換行,\t表示製表符,字元\本身也要轉義,所以\\表示的字元就是\,可以在Python的互動式命令列用print列印字串看看:

>>> print 'I\'m ok.'
I'm ok.
>>> print 'I\'m learning\nPython.'
I'm learning
Python.
>>> print '\\\n\\'
\
\

如果字串裡面有很多字元都需要轉義,就需要加很多\,為了簡化,Python還允許用r''表示''內部的字串預設不轉義,可以自己試試:

>>> print '\\\t\\'
\       \
>>> print r'\\\t\\'
\\\t\\

如果字串內部有很多換行,用\n寫在一行裡不好閱讀,為了簡化,Python允許用'''...'''的格式表示多行內容,可以自己試試:

>>> print '''line1
... line2
... line3'''
line1
line2
line3

上面是在互動式命令列內輸入,如果寫成程式,就是:

print '''line1
line2
line3'''

多行字串'''...'''還可以在前面加上r使用,請自行測試。

布林值

布林值和布林代數的表示完全一致,一個布林值只有TrueFalse兩種值,要麼是True,要麼是False,在Python中,可以直接用TrueFalse表示布林值(請注意大小寫),也可以通過布林運算計算出來:

>>> True
True
>>> False
False
>>> 3 > 2
True
>>> 3 > 5
False

布林值可以用andornot運算。

and運算是與運算,只有所有都為Trueand運算結果才是True

>>> True and True
True
>>> True and False
False
>>> False and False
False

or運算是或運算,只要其中有一個為Trueor運算結果就是True

>>> True or True
True
>>> True or False
True
>>> False or False
False

not運算是非運算,它是一個單目運算子,把True變成FalseFalse變成True

>>> not True
False
>>> not False
True

布林值經常用在條件判斷中,比如:

if age >= 18:
    print 'adult'
else:
    print 'teenager'
空值

空值是Python裡一個特殊的值,用None表示。None不能理解為0,因為0是有意義的,而None是一個特殊的空值。

此外,Python還提供了列表、字典等多種資料型別,還允許建立自定義資料型別,我們後面會繼續講到。

變數

變數的概念基本上和初中代數的方程變數是一致的,只是在計算機程式中,變數不僅可以是數字,還可以是任意資料型別。

變數在程式中就是用一個變數名錶示了,變數名必須是大小寫英文、數字和_的組合,且不能用數字開頭,比如:

a = 1

變數a是一個整數。

t_007 = 'T007'

變數t_007是一個字串。

Answer = True

變數Answer是一個布林值True

在Python中,等號=是賦值語句,可以把任意資料型別賦值給變數,同一個變數可以反覆賦值,而且可以是不同型別的變數,例如:

a = 123 # a是整數
print a
a = 'ABC' # a變為字串
print a

這種變數本身型別不固定的語言稱之為動態語言,與之對應的是靜態語言。靜態語言在定義變數時必須指定變數型別,如果賦值的時候型別不匹配,就會報錯。例如Java是靜態語言,賦值語句如下(// 表示註釋):

int a = 123; // a是整數型別變數
a = "ABC"; // 錯誤:不能把字串賦給整型變數

和靜態語言相比,動態語言更靈活,就是這個原因。

請不要把賦值語句的等號等同於數學的等號。比如下面的程式碼:

x = 10
x = x + 2

如果從數學上理解x = x + 2那無論如何是不成立的,在程式中,賦值語句先計算右側的表示式x + 2,得到結果12,再賦給變數x。由於x之前的值是10,重新賦值後,x的值變成12

最後,理解變數在計算機記憶體中的表示也非常重要。當我們寫:

a = 'ABC'

時,Python直譯器幹了兩件事情:

  1. 在記憶體中建立了一個'ABC'的字串;

  2. 在記憶體中建立了一個名為a的變數,並把它指向'ABC'

也可以把一個變數a賦值給另一個變數b,這個操作實際上是把變數b指向變數a所指向的資料,例如下面的程式碼:

a = 'ABC'
b = a
a = 'XYZ'
print b

最後一行打印出變數b的內容到底是'ABC'呢還是'XYZ'?如果從數學意義上理解,就會錯誤地得出ba相同,也應該是'XYZ',但實際上b的值是'ABC',讓我們一行一行地執行程式碼,就可以看到到底發生了什麼事:

執行a = 'ABC',直譯器建立了字串'ABC'和變數a,並把a指向'ABC'

執行b = a,直譯器建立了變數b,並把b指向a指向的字串'ABC'

執行a = 'XYZ',直譯器建立了字串'XYZ',並把a的指向改為'XYZ',但b並沒有更改:

所以,最後列印變數b的結果自然是'ABC'了。

常量

所謂常量就是不能變的變數,比如常用的數學常數π就是一個常量。在Python中,通常用全部大寫的變數名錶示常量:

PI = 3.14159265359

但事實上PI仍然是一個變數,Python根本沒有任何機制保證PI不會被改變,所以,用全部大寫的變數名錶示常量只是一個習慣上的用法,如果你一定要改變變數PI的值,也沒人能攔住你。

最後解釋一下整數的除法為什麼也是精確的,可以試試:

>>> 10 / 3
3

你沒有看錯,整數除法永遠是整數,即使除不盡。要做精確的除法,只需把其中一個整數換成浮點數做除法就可以:

>>> 10.0 / 3
3.3333333333333335

因為整數除法只取結果的整數部分,所以Python還提供一個餘數運算,可以得到兩個整數相除的餘數:

>>> 10 % 3
1

無論整數做除法還是取餘數,結果永遠是整數,所以,整數運算結果永遠是精確的。

小結

Python支援多種資料型別,在計算機內部,可以把任何資料都看成一個“物件”,而變數就是在程式中用來指向這些資料物件的,對變數賦值就是把資料和變數給關聯起來。

字串和編碼

字元編碼

我們已經講過了,字串也是一種資料型別,但是,字串比較特殊的是還有一個編碼問題。

因為計算機只能處理數字,如果要處理文字,就必須先把文字轉換為數字才能處理。最早的計算機在設計時採用8個位元(bit)作為一個位元組(byte),所以,一個位元組能表示的最大的整數就是255(二進位制11111111=十進位制255),如果要表示更大的整數,就必須用更多的位元組。比如兩個位元組可以表示的最大整數是65535,4個位元組可以表示的最大整數是4294967295

由於計算機是美國人發明的,因此,最早只有127個字母被編碼到計算機裡,也就是大小寫英文字母、數字和一些符號,這個編碼表被稱為ASCII編碼,比如大寫字母A的編碼是65,小寫字母z的編碼是122

但是要處理中文顯然一個位元組是不夠的,至少需要兩個位元組,而且還不能和ASCII編碼衝突,所以,中國製定了GB2312編碼,用來把中文編進去。

你可以想得到的是,全世界有上百種語言,日本把日文編到Shift_JIS裡,韓國把韓文編到Euc-kr裡,各國有各國的標準,就會不可避免地出現衝突,結果就是,在多語言混合的文字中,顯示出來會有亂碼。

因此,Unicode應運而生。Unicode把所有語言都統一到一套編碼裡,這樣就不會再有亂碼問題了。

Unicode標準也在不斷髮展,但最常用的是用兩個位元組表示一個字元(如果要用到非常偏僻的字元,就需要4個位元組)。現代作業系統和大多數程式語言都直接支援Unicode。

現在,捋一捋ASCII編碼和Unicode編碼的區別:ASCII編碼是1個位元組,而Unicode編碼通常是2個位元組。

字母A用ASCII編碼是十進位制的65,二進位制的01000001

字元0用ASCII編碼是十進位制的48,二進位制的00110000,注意字元'0'和整數0是不同的;

漢字已經超出了ASCII編碼的範圍,用Unicode編碼是十進位制的20013,二進位制的01001110 00101101

你可以猜測,如果把ASCI