目錄 | 上一節(1.5 列表) | 下一節 (1.7 函數)python
大多數的程序須要從某處讀取輸入。本節討論文件訪問。git
打開一個文件:github
f = open('foo.txt', 'rt') # Open for reading (text) g = open('bar.txt', 'wt') # Open for writing (text)
讀取全部的數據:segmentfault
data = f.read() # Read only up to 'maxbytes' bytes data = f.read([maxbytes])
寫入一些文本:bash
g.write('some text')
當你完成操做後,關閉文件:函數
f.close() g.close()
文件應該被正確地關閉,這是很容易忘記的一個步驟。所以,首選方法是像下面這樣使用 with
語句:學習
with open(filename, 'rt') as file: # Use the file `file` ... # No need to close explicitly ...statements
當控制流離開縮進的代碼塊時,這將會自動關閉文件。編碼
以字符串的形式一次性讀取整個文件:翻譯
with open('foo.txt', 'rt') as file: data = file.read() # `data` is a string with all the text in `foo.txt`
經過迭代逐行讀取文件:code
with open(filename, 'rt') as file: for line in file: # Process the line
寫入字符串數據:
with open('outfile', 'wt') as out: out.write('Hello World\n') ...
重定向 print() 函數:
with open('outfile', 'wt') as out: print('Hello World', file=out) ...
本練習依賴於 Data/portfolio.csv
文件。該文件由一行一行的關於股票投資組合的信息構成。假定你是在 practical-python/Work/
目錄下進行操做。若是你不肯定本身所在的目錄,你能夠經過執行如下操做找出 Python 運行的目錄:
>>> import os >>> os.getcwd() '/Users/beazley/Desktop/practical-python/Work' # Output vary >>>
首先,嘗試以字符串的形式一次性讀取整個文件:
>>> with open('Data/portfolio.csv', 'rt') as f: data = f.read() >>> data 'name,shares,price\n"AA",100,32.20\n"IBM",50,91.10\n"CAT",150,83.44\n"MSFT",200,51.23\n"GE",95,40.37\n"MSFT",50,65.10\n"IBM",100,70.44\n' >>> print(data) name,shares,price "AA",100,32.20 "IBM",50,91.10 "CAT",150,83.44 "MSFT",200,51.23 "GE",95,40.37 "MSFT",50,65.10 "IBM",100,70.44 >>>
在上面的示例中,應注意 Python 有兩種輸出模式。在第一種模式下,你在提示符後輸入 data
,Python 向你展現包含引號和轉義碼的原始字符串。當你輸入 print(data)
時,你得到真正的字符串的格式化輸出。
一次性讀取文件很簡單,但這一般不是最恰當的讀取文件方式——尤爲是當文件碰巧很大或者文件包含要一次性處理的文本行時。
要逐行讀取文件,能夠像下面這樣使用 for 循環:
>>> with open('Data/portfolio.csv', 'rt') as f: for line in f: print(line, end='') name,shares,price "AA",100,32.20 "IBM",50,91.10 ... >>>
當你像上面展現的那樣使用此代碼時,它會讀取文件的每一行,直到到達文件末尾。在文件末尾,循環會中止。
在某些特定的狀況下,你可能想要手動的讀取或者跳過某一行文本(例如,可能你想跳過列標題的第一行):
>>> f = open('Data/portfolio.csv', 'rt') >>> headers = next(f) >>> headers 'name,shares,price\n' >>> for line in f: print(line, end='') "AA",100,32.20 "IBM",50,91.10 ... >>> f.close() >>>
next()
函數返回文件中的下一行文本。若是你反覆調用該函數,將會得到連續的行。可是,如你所知,for
循環已經使用 next()
函數獲取數據了。因此,一般狀況下,除非你像上面展現的那樣試圖顯式跳過或者讀取一行,不然,不要直接調用 next()
函數。
一旦讀取文件的各行,你就能夠開始執行更多的操做,例如拆分。
示例,嘗試如下操做:
>>> f = open('Data/portfolio.csv', 'rt') >>> headers = next(f).split(',') >>> headers ['name', 'shares', 'price\n'] >>> for line in f: row = line.split(',') print(row) ['"AA"', '100', '32.20\n'] ['"IBM"', '50', '91.10\n'] ... >>> f.close()
注意:在這些示例中,由於沒有使用 with
語句,因此 f.close()
被顯式的調用。
如今你已經知道如何讀取文件,讓咱們編寫一個程序來執行簡單的計算。
portfolio.csv
文件裏面的列對應股票的名稱,股票的數量以及單支股票持有的購買價格。編寫一個名爲 pcost.py
的程序來打開這個文件,讀取全部的行而且計算在全部的股票投資組合中花費多少錢來購買這些股份。
提示:要將字符串轉爲整數,使用 int()
函數。要將字符串轉爲浮點數,使用 float()
函數。
你的程序應該打印以下輸出:
Total cost 44671.15
若是你想讀取非文本文件(如 gzip 壓縮的數據文件)怎麼辦?雖然內建 open()
函數在這裏幫不了你了,可是 Python 提供的 gzip
模塊能夠讀取 gzip 文件。
試試看:
>>> import gzip >>> with gzip.open('Data/portfolio.csv.gz', 'rt') as f: for line in f: print(line, end='') ... look at the output ... >>>
注意:此處包含 'rt'
文件模式相當重要。若是你忘記使用它,你將會獲得字節字符串而不是一般的文本字符串。
數據科學家很快指出,諸如 Pandas 這樣的庫已經具備讀取 CSV 文件的函數,爲何不使用 Pandas 呢?的確如此——並且效果也很好。可是,這不是一門有關學習 Pandas 的課程,讀取文件是一個比讀取 CSV 文件更廣泛的問題。咱們使用 CSV 文件作例子的主要緣由是:它是大多數編碼人員熟悉的格式,而且相對易於直接使用——在讀取 CSV 文件的過程當中,闡明瞭許多 Python 特性。因此,當你回到工做中,請務必使用 Pandas。可是,在本課程剩下部分,咱們將會繼續使用標準的 Python 函數。