翻譯:《實用的Python編程》03_06_Design_discussion
目錄 | 上一節(jié) (3.5 主模塊) | 下一節(jié) (4 類)
3.6 設(shè)計討論
本節(jié),我們重新考慮之前所做的設(shè)計決策。
文件名與可迭代對象
考慮以下兩個返回相同輸出的程序。
# Provide a filename
def read_data(filename):
records = []
with open(filename) as f:
for line in f:
...
records.append(r)
return records
d = read_data('file.csv')
# Provide lines
def read_data(lines):
records = []
for line in lines:
...
records.append(r)
return records
with open('file.csv') as f:
d = read_data(f)
- 你更傾向于使用哪個函數(shù)?為什么?
- 哪個函數(shù)更靈活?
鴨子類型(Duck Typing)
在計算機程序設(shè)計中,鴨子類型 用于確定一個對象是否可用于特定目的。這是 鴨子測試 的一種應(yīng)用。
如果它看起來像鴨子、游泳像鴨子、叫聲像鴨子,那么它可能就是只鴨子。
上述第二個 read_data() 函數(shù)接受任何可迭代對象,而不僅是文件行。
def read_data(lines):
records = []
for line in lines:
...
records.append(r)
return records
這意味著我們可以使用它處理其它的行(lines)。
# A CSV file
lines = open('data.csv')
data = read_data(lines)
# A zipped file
lines = gzip.open('data.csv.gz','rt')
data = read_data(lines)
# The Standard Input
lines = sys.stdin
data = read_data(lines)
# A list of strings
lines = ['ACME,50,91.1','IBM,75,123.45', ... ]
data = read_data(lines)
這種設(shè)計具有很大的靈活性。
問題:我們應(yīng)該擁抱還是反對這種靈活性?
庫設(shè)計最佳實踐
通常,擁抱靈活性可以更好的服務(wù)于代碼庫。不要限制你的選擇,靈活性大,帶來的威力也大。
練習
練習 3.17:從文件名到類文件對象
現(xiàn)在,你已經(jīng)創(chuàng)建了一個包含 parse_csv() 函數(shù)的 fileparse.py 文件。parse_csv() 函數(shù)像下面這樣工作:
>>> import fileparse
>>> portfolio = fileparse.parse_csv('Data/portfolio.csv', types=[str,int,float])
>>>
雖然函數(shù)接受的是一個文件名,但是,你可以使代碼更具靈活性。請求修改函數(shù),以便它可以接受任何類文件或者可迭代對象。例如:
>>> import fileparse
>>> import gzip
>>> with gzip.open('Data/portfolio.csv.gz', 'rt') as file:
... port = fileparse.parse_csv(file, types=[str,int,float])
...
>>> lines = ['name,shares,price', 'AA,100,34.23', 'IBM,50,91.1', 'HPE,75,45.1']
>>> port = fileparse.parse_csv(lines, types=[str,int,float])
>>>
在新的代碼中,如果像以前一樣傳遞一個文件名會發(fā)生什么?
>>> port = fileparse.parse_csv('Data/portfolio.csv', types=[str,int,float])
>>> port
... look at output (it should be crazy) ...
>>>
正如上面代碼顯示的那樣,這可能帶來意想不到的結(jié)果,所以,修改的時候需要小心一些。你可以添加安全檢查來避免這種情況嗎?
練習 3.18:修復(fix)現(xiàn)有函數(shù)
請修復 report.py 文件中的 read_portfolio() 和 read_prices() 函數(shù)。以便它們可以使用修改后的 parse_csv() 函數(shù)。這應(yīng)該只涉及較小的修改。之后,report.py 和 pcost.py 程序應(yīng)能夠像以往一樣工作。
浙公網(wǎng)安備 33010602011771號