2.1 引言
譯者:飛龍
在第一章中,我們專注於計算過程,以及程序設計中函數的作用。我們看到了如何使用原始數據(數值)和原始操作(算術運算),如何通過組合和控制來形成複合函數,以及如何通過給予過程名稱來創建函數抽象。我們也看到了高階函數通過操作通用計算方法來提升語言的威力。這是編程的本質。
這一章會專注於數據。數據允許我們通過使用已經獲得的計算工具,表示和操作與世界有關的信息。脫離數據結構的編程可能會滿足於探索數學特性,但是真實世界的情況,比如文檔、關係、城市和氣候模式,都擁有複雜的結構,它最好使用複合數據類型來表現。歸功於互聯網的高速發展,關於世界的大量結構信息可以免費從網上獲得。
2.1.1 對象隱喻
在這門課的開始,我們區分了函數和數據:函數執行操作,而數據被操作。當我們在數據中包含函數值時,我們承認數據也擁有行為。函數可以像數據一樣被操作,但是也可以被調用來執行計算。
在這門課中,對象作為我們對數據值的核心編程隱喻,它同樣擁有行為。對象表示信息,但是同時和它們所表示的抽象概念行為一致。對象如何和其它對象交互的邏輯,和編碼對象值的信息綁定在一起。在打印對象時,它知道如何以字母和數字把自己拼寫出來。如果一個對象由幾部分組成,它知道如何按照要求展示這些部分。對象既是信息也是過程,它們綁定在一起來展示覆雜事物的屬性、交互和行為。
Python 中所實現的對象隱喻具有特定的對象語法和相關的術語,我們會使用示例來介紹。日期(date)就是一種簡單對象。
>>> from datetime import date
date的名字綁定到了一個類上面。類表示一類對象。獨立的日期叫做這個類的實例,它們可以通過像函數那樣在參數上調用這個類來構造,這些參數描述了實例。
>>> today = date(2011, 9, 12)
雖然today從原始數值中構造,它的行為就像日期那樣。例如,將它與另一個日期相減會得到時間差,它可以通過調用str來展示為一行文本:
>>> str(date(2011, 12, 2) - today)
'81 days, 0:00:00'
對象擁有屬性,它們是帶有名字的值,也是對象的一部分。Python 中,我們使用點運算符來訪問對象屬性:
<expression> . <name>
上面的<expression>求值為對象,<name>是對象的某個屬性名稱。
不像我們之前見過的名稱,這些屬性名稱在一般的環境中不可用。反之,屬性名稱是點運算符之前的對象實例的特定部分。
>>> today.year
2011
對象也擁有方法,它是值為函數的屬性。在隱喻上,對象“知道”如何執行這些方法。方法從它們的參數和對象中計算出它們的結果。例如,today的strftime方法接受一個指定如何展示日期的參數(例如%A表示星期幾應該以全稱拼寫)。
>>> today.strftime('%A, %B %d')
'Monday, September 12'
計算strftime的返回值需要兩個輸入:描述輸出格式的字符串,以及綁定到today的日期信息。這個方法使用日期特定的邏輯來產生結果。我們從不會說 2011 年九月十二日是星期一,但是知道一個人的工作日是日期的一部分。通過綁定行為和信息,Python 對象提供了可靠、獨立的日期抽象。
點運算符在 Python 中提供了另一種組合表達式。點運算符擁有定義好的求值過程。但是,點運算符如何求值的精確解釋,要等到我們引入面向對象編程的完整範式,在幾節之後。
即使我們還不能精確描述對象如何工作,我們還是可以開始將數據看做對象,因為 Python 中萬物皆對象。
2.1.2 原始數據類型
Python 中每個對象都擁有一個類型。type函數可以讓我們查看對象的類型。
>>> type(today)
<class 'datetime.date'>
目前為止,我們學過的對象類型只有數值、函數、布爾值和現在的日期。我們也碰到了集合和字符串,但是需要更深入地學習它們。有許多其它的對象類型 -- 聲音、圖像、位置、數據連接等等 -- 它們的多數可以通過組合和抽象的手段來定義,我們在這一章會研究它們。Python 只有一小部分內建於語言的原始或原生數據類型。
原始數據類型具有以下特性:
- 原始表達式可以計算這些類型的對象,叫做字面值。
- 內建的函數、運算符和方法可以操作這些對象。
像我們看到的那樣,數值是原始類型,數字字面值求值為數值,算術運算符操作數值對象:
>>> 12 + 3000000000000000000000000
3000000000000000000000012
實際上,Python 包含了三個原始數值類型:整數(int)、實數(float)和複數(complex)。
>>> type(2)
<class 'int'>
>>> type(1.5)
<class 'float'>
>>> type(1+1j)
<class 'complex'>
名稱float來源於實數在 Python 中表示的方式:“浮點”表示。雖然數值表示的細節不是這門課的話題,一些int和float對象的高層差異仍然很重要。特別是,int對象只能表示整數,但是表示得更精確,不帶有任何近似。另一方面,float對象可以表示很大範圍內的分數,但是不能表示所有有理數。然而,浮點對象通常用於近似表示實數和有理數,舍入到某個有效數字的數值。
**擴展閱讀。**下面的章節介紹了更多的 Python 原始數據類型,專注於它們在創建實用數據抽象中的作用。Dive Into Python 3 中的原始數據類型一章提供了所有 Python 數據類型的實用概覽,以及如何高效使用它們,還包含了許多使用示例和實踐提示。你現在並不需要閱讀它,但是要考慮將它作為寶貴的參考。