目錄 | 上一節 (3.5 主模塊) | 下一節 (4 類)html
本節,咱們從新考慮以前所作的設計決策。python
考慮如下兩個返回相同輸出的程序。git
# 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)
在計算機程序設計中,鴨子類型 用於肯定一個對象是否可用於特定目的。這是 鴨子測試 的一種應用。github
若是它看起來像鴨子、游泳像鴨子、叫聲像鴨子,那麼它可能就是隻鴨子。安全
上述第二個 read_data()
函數接受任何可迭代對象,而不只是文件行。app
def read_data(lines): records = [] for line in lines: ... records.append(r) return records
這意味着咱們能夠使用它處理其它的行(lines)。ide
# 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)
這種設計具備很大的靈活性。函數
問題:咱們應該擁抱仍是反對這種靈活性?測試
一般,擁抱靈活性能夠更好的服務於代碼庫。不要限制你的選擇,靈活性大,帶來的威力也大。翻譯
如今,你已經建立了一個包含 parse_csv()
函數的 fileparse.py
文件。parse_csv()
函數像下面這樣工做:
>>> import fileparse >>> portfolio = fileparse.parse_csv('Data/portfolio.csv', types=[str,int,float]) >>>
雖然函數接受的是一個文件名,可是,你能夠使代碼更具靈活性。請求修改函數,以便它能夠接受任何類文件或者可迭代對象。例如:
>>> 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]) >>>
在新的代碼中,若是像之前同樣傳遞一個文件名會發生什麼?
>>> port = fileparse.parse_csv('Data/portfolio.csv', types=[str,int,float]) >>> port ... look at output (it should be crazy) ... >>>
正如上面代碼顯示的那樣,這可能帶來意想不到的結果,因此,修改的時候須要當心一些。你能夠添加安全檢查來避免這種狀況嗎?
請修復 report.py
文件中的 read_portfolio()
和 read_prices()
函數。以便它們能夠使用修改後的 parse_csv()
函數。這應該只涉及較小的修改。以後,report.py
和 pcost.py
程序應可以像以往同樣工做。
目錄 | 上一節 (3.5 主模塊) | 下一節 (4 類)