這段時間讀到了第二章,這一章感覺比第一章要難一點,講的也更抽象。
對於英文不好的我來說,只能選擇我覺得重要的點記錄一下,並實現裏面的全部程序。
1. 介紹
第一章中瞭解了計算過程和函數在編程設計中的作用。知道了怎麼用原始數據和原始操作符,怎樣組成複合函數,創建函數的抽象,瞭解了高階函數,這些是編程的本質。
本章重點是數據。
1.1. 對象的比喻
分清函數和數據:函數對數據進行操作。當將函數作爲數據是,承認數據也有行爲。函數能像數據那樣被操作,也叫做執行操縱。對象(object)包含了信息和過程,具有屬性,交互和複雜行爲。
a data is a kind of simple object.
from datetime import data
data是一種類。具體的日期是類的一個實例。可以通過調研調用類的構造函數來實例化一個類。
today = date(2011, 9 ,12)
當被實例化後,today就成爲了數據。
對象有屬性,是對象的一部分。python用.號指定對象的一個屬性。
experssion.name
today.year #2011
對象也有方法,方法根據參數和對象計算其結果。
today.strftime('%A, %B %d') #'Monday, September 12'
儘管還沒有清晰描述對象是如何工作的,但是是時候將數據作爲對象考慮了,python中一切都是對象。
1.2. 原始數據類型
任何對象在python都有類型。
>>> type(today)
<class ’datetime.date’>
聲音,圖形等都是數據,都能被抽象表示,都能被python基本的數據類型表示。
基本數據(native or primitive data)有如下兩個屬性:
1. 有基本表達式來對這些基本對象進行計算,稱爲字面值。
2. 有內置函數,操作符和操作這些對象的方法。
python有三種基本數據類型。int 和float 和complex。
2. 數據抽象
數據抽象是一種方法論,使我們不必考慮複合數據對象構造的細節,從而使用它。
數據抽象的基本思想是構造函數以便於對操作對抽象數據進行處理。我們的程序應該用這樣的抽象數據而儘量少用假設的數據。
構造器和選擇器:實現抽象數據方面的具體表現。
記住計算機科學不僅僅是學會如何使用一門語言,而應該深入瞭解它是如何工作的。
2.1. 有理數的四則運算
在實現程序的部分功能之後,我們就可可以用函數抽象開始高效率編程了。
假設我們已經實現了方法:給一個有理數,可以得到分子和分母。這樣就可以得到如下的構造器和選擇器。
• make_rat(n, d) returns the rational number with numerator n and denominator d.
• numer(x) returns the numerator of the rational number x.
• denom(x) returns the denominator of the rational number x.
這裏我們用到一種強有力的策略:wishful thinking。儘管還沒有對這三個函數進行實現。假設如果我們有了這三個函數,就可以調用它們對有理數進行加,乘,判斷相等操作。
>>> def add_rat(x, y):
nx, dx = numer(x), denom(x)
ny, dy = numer(y), denom(y)
return make_rat(nx * dy + ny * dx, dx * dy)
>>> def mul_rat(x, y):
return make_rat(numer(x) * numer(y), denom(x) * denom(y))
>>> def eq_rat(x, y):
return numer(x) * denom(y) == numer(y) * denom(x)
現在已經有了構造器(make_rat)和選擇器(numer和demon),但是還沒有實現它們。我們需要一種方法將分子和分聚合在一個單元。
元組(tuples)
基本操作:
元組的元素可以通過兩種方式獲得:
>>> pair = (1, 2)
>>> pair
(1, 2)
>>> x, y = pair
>>> x
1
>>> y
2
>>> pair[0]
1
>>> pair[1]
2
下標:從0開始。一種約定:下標表示一個元素偏離元組開始元素的距離。
表示有理數:程序如下:
from operator import getitem
from fractions import gcd #導入求最大公約數的函數gcd
def make_rat(n, d): #returns the rational number with numerator n and denominator d
g = gcd(n, d)
return (n//g, d//g)
def numer(x): #returns the numerator of the rational number x.
return getitem(x, 0)
def denom(x): #returns the denominator of the rational number x.
return getitem(x, 1)
def add_rat(x, y):
nx, dx = numer(x), denom(x)
ny, dy = numer(y), denom(y)
return make_rat(nx * dy + ny * dx, dx * dy)
def mul_rat(x, y):
return make_rat(numer(x) * numer(y) ,denom(x) * denom(y))
def eq_rat(x, y):
return numer(x) * denom(y) == numer(y) * denom(x)
def str_rat(x):
"""return a string 'n/d' for numerator n and demominator d."""
return '{0}/{1}'.format(numer(x), denom(x))
half = make_rat(1, 2)
print(str_rat(half)) #1/2
third = make_rat(1, 3)
print(str_rat(third)) #1/3
print(str_rat(mul_rat(half, third))) #1/6
print(str_rat(add_rat(third, third))) #2/3
2.3. 抽象界限
一般來說,數據抽象的根本思想是爲了給每種類型的值確定一種基本操作,就這種操作來說,所有的類型的值將被表達,然後只使用這些這些操作在操縱數據。。
抽象界限提供了好多好處:一個好處是使程序維護和修改更加簡單。較小的函數取決與特定的表式,當需要改變時只需要做少量的修改。
2.4. 數據屬性
def make_pair(x, y):
"""
return a function that behaves like a pair.
"""
def dispatch(m):
if 0 == m:
return x
elif 1 == m:
return y
return dispatch
def getitem_pair(p, i):
"""
Return the element at index i of pair p.
"""
return p(i)
p = make_pair(4, 5)
print(getitem_pair(p, 0))
#4
print(getitem_pair(p, 1))
#5