Python 是一種敏捷的、動態型別化的、極富表現力的開源程式語言,可以被自由地安裝到多種平臺上。Python 程式碼是被解釋的。如果您對編輯、構建和執行迴圈較為熟悉,則 Python 程式碼對您來說更簡單。但是,請不要搞錯:Python 器可以是簡單的指令碼,也可以是大型的複雜程式。事實上,Python 直譯器的最大特點是鼓勵探索和簡化學習過程。如果您想證明這一點,請使用 Python 編寫著名的 Hello World! 程式:
- 啟動 Python 直譯器。在 UNIX 系統(包括 Mac OS X)中,啟動直譯器通常包括在命令提示行鍵入
python
;在 Microsoft® Windows® 系統中,啟動 Python 命令 shell。 - 在 Python 提示行中,在三個大於號 (
>>>
) 標誌後輸入 print ‘Hello World!
‘,然後按 Enter。 - 完成:沒有第三步了。清單 1 顯示了此命令的輸出。
清單 1. 用 Python 編寫的 “Hello World” 的輸出
1 2 3 4 5 6 |
rb% python Python 2.4 (#1, Mar 29 2005, 12:05:39) [GCC 3.3 20030304 (Apple Computer, Inc. build 1495)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> print 'Hello World!' Hello World! |
您可以看到,我使用的是執行於 Apple OS X 系統上的 Python V2.4。但是,不管作業系統是什麼,基本原理都是一樣的,而且在本例中,所用的是 Python 的哪一個實際版本也無所謂。我雖然不瞭解您,但是此 Hello World! 練習比我學過的 C、C++ 甚至 Java™ 語言的對應練習容易多了。這種簡單性就是使用 Python 直譯器的主要優點之一。開發人員可以快速試驗一個想法、研究一種物件屬性或不同演算法,而無需編譯、執行和測試任何程式碼。
Python 型別層次結構
從其他語言過渡到 Python 程式語言時需要學習的最重要的課程之一是,Python 中的每樣東西都是物件。這一點可能並沒有什麼特別之處,尤其是對於熟悉物件導向的語言(如 C++、Java 或 C#)的人來說。然而,Python 的物件導向原理與其他語言不同,主要表現在兩個方面:第一,Python 中的所有資料值都被封裝在相關物件類中。第二,Python 程式中的所有東西都是可以從程式訪問的物件,即使是您編寫的程式碼也不例外。
大多數流行的程式語言都有多個內建的資料型別,在這一方面 Python 也一樣。例如,C 程式語言具有整型和浮點型別。由於譜系相同,Java 語言和 C# 具有內建型別也不足為奇。這意味著在 C 程式中,可以編寫 int i = 100
來建立和初始化整型變數。在 Java 和 C# 中,此方法也是可能的,而且使用它們的自動裝箱功能,在需要時這兩種語言還可以把這種簡單的內建型別轉換為 Integer
物件。
另一方面,Python 不包含像 int 這樣的簡單型別 —— 只有物件型別。如果 Python 中需要整數值,將整數賦值給相應變數(如 i = 100
)即可。在後臺,Python 將建立一個整數物件,並將對新物件的引用賦值給變數。問題的關鍵是:Python 是一種動態型別化語言,所以無需宣告變數型別。事實上在單個程式中,變數的型別是可以改變(多次)的。
一種直觀演示動態型別化工作方式的簡單方法是,設想單個名為 PyObject
的基類,讓 Python 中的所有其他物件型別都繼承它。在這一模型中,您建立的所有變數都將引用在總的類層次結構中建立的物件。如果您還讓 PyObject
類記錄曾建立並分配給變數的子類的實際型別或名稱,則 Python 程式可正確確定程式執行過程中需要採取的步驟。
上一段描述 Python 的物件導向的模型影像是對 Python 的實際工作方式很好的模擬。除此之外,Python 還可以使用型別函式來簡化對變數型別的確定。(本例還介紹如何使用帶有 # 字元的內聯註釋。)
清單 2. 演示 Python 簡單型別
1 2 3 4 5 6 |
>>> i = 100 # Create an int object whose value is 100 >>> type(i) <type 'int'> >>> f = 100.0 >>> type(f) <type 'float'> |
可以將 PyObject
類之下的所有 Python 類劃分為 Python 執行時直譯器可以使用的四個主要類別:
- 簡單型別 —— 基本構建塊,如
int
和float
。 - 容器型別 —— 儲存其他物件。
- 程式碼型別 —— 封裝 Python 程式的元素。
- 內部型別 —— 程式執行期間使用的型別。
到本系列結束時,我會把所有不同類別都介紹給大家。但是在這第一篇文章中,我重點介紹簡單型別。
簡單型別
Python 有五個內建的簡單型別:bool
、int
、long
、float
和 complex
。這些型別是不可變的,就是說整數物件一旦建立,其值便不可更改。相反,系統將建立新的簡單型別物件並將其賦值給變數。通過 Python id
函式,可以檢視基本 PyObject
標識的變更方式:
清單 3. 使用 Python id
函式
1 2 3 4 5 6 |
>>> i = 100 >>> id(i) 8403284 >>> i = 101 >>> id(i) 8403296 |
此方法看似容易丟失物件,會導致記憶體洩漏。但是,Python 像 C# 和 Java 一樣,使用了垃圾回收功能,以釋放用於儲存不再引用的物件的記憶體,如上例中用於儲存 100 的整數物件。
布林型別
Python 中最簡單的內建型別是 bool
型別,該型別包括的物件僅可能為 True
或 False
:
清單 4. bool
型別
1 2 3 4 5 |
>>> b = True >>> type(b) <type 'bool'> >>> id(b) 1041552 |
因為只有兩個可能值,所以布林型別是惟一的。Python 直譯器提供這僅有的(也是必需的)兩個 bool
物件:True
和 False
。在任何時候,在 Python 程式需要這些物件時,變數只能相應地引用其中一個值。清單 5 顯示 bb
變數如何具有同一個 id
,不管您直接賦予它 b
變數的值還是直接賦予它 True
物件。
清單 5. bb
變數的值
1 2 3 4 5 6 7 8 9 |
>>> b = True >>> id(b) 1041552 >>> bb = b >>> id(bb) 1041552 >>> bb = True >>> id(bb) 1041552 |
布林物件名稱的大小寫是至關重要的,因為 true(和 false)是未定義的:
清單 6. 未定義的 true 和 false
1 2 3 4 |
>>> b = true Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'true' is not defined |
在這一點上,bool
型別可能看起來不是很有用。不過顧名思義,布林表示式是依賴於名稱的,如下所示:
清單 7. 布林表示式
1 2 3 |
>>> b = 100 < 101 >>> print b True |
很多程式利用布林表示式,Python 提供一整套布林比較和邏輯運算,詳細資訊請分別參見表 1 和表 2。
表 1. Python 中的布林比較運算子
運算子 | 描述 | 示例 |
---|---|---|
< | 小於 | i < 100 |
<= | 小於等於 | i <= 100 |
> | 大於 | i > 100 |
>= | 大於等於 | i >= 100 |
== | 相等 | i == 100 |
!= | 不相等(另外使用 <>) | i != 100 |
補充一點,表 1 中列出的運算子優先順序都一樣,除非將表示式置於括號中,否則按從左到右的順序應用。
表 2. Python 中的邏輯運算子
運算子 | 描述 | 示例 |
---|---|---|
not |
邏輯非 | not b |
and |
邏輯與 | (i <= 100) and (b == True) |
or |
邏輯或 | (i < 100) or (f > 100.1) |
邏輯運算子的優先順序低於單獨的比較運算子,這一點意義重大,因為必須先計算比較運算子,然後才能計算邏輯運算子。邏輯運算子的實際優先順序就是表 2 中羅列這些運算子的順序。
在 Python 中,關於 or
和 and
邏輯運算子有意思的是,它們都是快捷運算子。簡言之,如果給定表示式 x
or y
,則僅當 x
為 False
時才會計算 y
。同樣地,如果給定表示式 x
and y
,則僅當 x
為 True
時,才會計算 y
。此功能可以增強表示式求值的效能(尤其是針對長的或複雜的表示式),然而對於習慣於從其他語言學來的不同規則的程式設計師而言,則容易犯錯。
數值型別
Python 中其他四個簡單的內建型別都是數值型別:int
、long
、float
和 complex
。在程式中,數值型別很常見,不管使用的是什麼語言。Python 對算術運算提供完整支援,包括加法、減法、乘法和除法(參見表 3)。
表 3. Python 中的算術運算
運算子 | 描述 | 示例 |
---|---|---|
* | 乘 | i * 100 |
/ | 除 | i / 100 |
// | 整除 | i // 100 |
% | 取餘 | f % 100 |
+ | 加 | i + 100 |
– | 減 | i - 100 |
乘法和除法運算子(表 3 中列出的前四個)具有高於加法和減法的優先順序。如前所述,您可以通過使用括號分組子表示式,將其分離出來以提高優先順序。
Python 與 Java 語言不同,Java 語言通常定義允許的數值型別的範圍,而 Python 在這一點上更像 C,因為它的型別範圍是依賴於平臺的。您可以使用 int
和 long
兩種型別來儲存整數值,它們的不同點在於 int 是一種 32 位的整數值。因而,它被限制為只能儲存從 -232 到 232 – 1 之間的值(在多數平臺上)。與此相反,長整數型別的精度不受限,僅計算機記憶體對它有影響。要通知 Python 應該按照長型別處理整數,只需將 L附加到數字的末尾,如 100L。在 Python 中,浮點值始終是按雙精度處理的;因此 Python 的 float
型別對應於 C 類語言中的雙精度。
與數值型別相關的其他兩個重點是常量(如上例中的 100,只是明確表達的數字)和位運算。程式設計師一般在十進位制系統(以 10 為基數)中工作。但是,有時其他系統也相當有用,尤其是我們知道計算機是基於二進位制的。Python 可以提供對八進位制(以 8 為基數)和十六進位制(以 16 為基數)數字的支援。要通知 Python 應該按八進位制數字常量處理數字,只需將零附加在前面。將一個零加上一個 x 附加在數字的前面是告訴 Python 按十六進位制數值常量處理數字,如以下程式碼所示:
清單 8. 通知 Python 按十六進位制數值常量處理數字
1 2 3 4 5 6 |
>>> print 127 # Using decimal literal 127 >>> print 0177 # Using octal literal 127 >>> print 0x7F # Using hexadecimal literal 127 |
當您具有容易的方式來表達數值常量時,尤其是十六進位制,就可以容易地構建對應於特定測試用例的標誌,這是一種常見的程式設計技術。例如,一個 32 位的整數可以儲存 32 個標誌值。使用位測試,可以容易地測試標誌變數上的特定標誌。Python 中位運算的完整列表如表 4 所示。
表 4. Python 中的位運算
運算子 | 描述 | 示例 |
---|---|---|
~ | 按位求補 | ~b |
<< | 向左位移 | b << 1 |
>> | 向右位移 | b >> 1 |
& | 按位和 | b & 0x01 |
^ | 按位異或 | b ^ 0x01 |
| | 按位或 | b | 0x01 |
至此,您可能想知道不同數值型別在單個表示式中混合出現的時候怎麼辦。簡單的答覆是,Python 會根據需要將表示式中的所有運算元轉換為最複雜的運算元的型別。複雜度的順序是:int
、long
、float
和 complex
(非雙關),下面是一個簡單的示例:
清單 9. Python 將所有運算元轉換為最複雜的運算元
1 2 3 4 5 6 7 8 9 10 |
>>> 1 / 3 0 >>> 1.0 / 3 0.33333333333333331 >>> 1.0 // 3 0.0 >>> 1 % 3 1 >>> 1.0 % 3 1.0 |
儘管 Python 會與您預期的一樣轉換運算元,但是語言並不基於運算子轉換運算元,如 1/3 示例中所示,其計算結果為整數。如果要強制取得浮點結果,則必須確保運算元中至少有一個為浮點型別。
complex 型別
最後一種型別 complex
可能是大多數程式設計師難以識別的,因為它不是其他程式語言中常見的內建資料型別。而對於工程師和科學家來說,複數卻是個司空見慣的概念。從形式上講,複數 具有實部和虛部兩個部分,都由 Python 中的 float
型別來表示。虛數 是 -1 的平方根的倍數,用 i或 j 表示 —— 取決於您被培養為科學家還是工程師。在 Python 中,複數的虛部被表示為 j:
清單 10. 複數的虛部
1 2 3 4 5 |
>>> c = 3.0 + 1.2j >>> print c (3+1.2j) >>> print c.real, c.imag 3.0 1.2 |
本例是一個實部為 3.0 和虛部為 1.2 的複數。注意,通過使用複雜物件的 real
和 imag
屬性,即可訪問複數的不同部分。
它們真是物件嗎?
到此為止,我已經介紹了 Python 只處理物件型別,然而示例中好像並沒有什麼物件。最後還有一個問題,建構函式在哪裡?對於簡單的內建資料型別,Python 替您做了大量的工作。不過,建構函式還在那裡(其名稱與相關資料型別的名稱相同),如果您願意,可以直接使用它們,如下所示:
清單 11. Python 建構函式
1 2 3 4 5 |
>>> c = 3.0 + 1.2j >>> print c (3+1.2j) >>> print c.real, c.imag 3.0 1.2 |
結束語
Python 是一種無比簡單又功能強大的語言。入門極其容易,尤其是對於已經具有 C 類語言的經驗的程式設計師來說。本文簡單介紹了 Python 程式語言和內建資料型別:bool
、int
、long
、float
和 complex
。如果您尚未理解,則請啟動一個 Python 直譯器,並嘗試按照我上面討論的方法操作。您將會很高興,我做到的您也可以做到。