一文搞懂Python讀取text,CSV,JSON文件的方法
前言
文件是無處不在的,無論我們使用哪種編程語言,處理文件對于每個程序員都是必不可少的
文件處理是一種用于創(chuàng)建文件、寫入數(shù)據(jù)和從中讀取數(shù)據(jù)的過程,Python 擁有豐富的用于處理不同文件類型的包,從而使得我們可以更加輕松方便的完成文件處理的工作
本文大綱:
- 使用上下文管理器打開文件
- Python 中的文件讀取模式
- 讀取 text 文件
- 讀取 CSV 文件
- 讀取 JSON 文件
打開文件
在訪問文件的內(nèi)容之前,我們需要打開文件。Python 提供了一個內(nèi)置函數(shù)可以幫助我們以不同的模式打開文件。open()
函數(shù)接受兩個基本參數(shù):文件名和模式
默認模式是“r”,它以只讀方式打開文件。這些模式定義了我們?nèi)绾卧L問文件以及我們?nèi)绾尾僮髌鋬?nèi)容。open()
函數(shù)提供了幾種不同的模式,我們將在后面逐一討論
下面我們通過 ’Python 之禪‘ 文件來進行后面的討論學習
f?=?open('zen_of_python.txt',?'r') print(f.read()) f.close()
Output:
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
...
在上面的代碼中,open()
函數(shù)以只讀模式打開文本文件,這允許我們從文件中獲取信息而不能更改它。在第一行,open()
函數(shù)的輸出被賦值給一個代表文本文件的對象 f
,在第二行中,我們使用 read()
方法讀取整個文件并打印其內(nèi)容,close()
方法在最后一行關(guān)閉文件。需要注意,我們必須始終在處理完打開的文件后關(guān)閉它們以釋放我們的計算機資源并避免引發(fā)異常
在 Python 中,我們可以使用 with
上下文管理器來確保程序在文件關(guān)閉后釋放使用的資源,即使發(fā)生異常也是如此
with?open('zen_of_python.txt')?as?f: ????print(f.read())
Output:
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
...
上面的代碼使用 with
語句創(chuàng)建了一個上下文,并綁定到變量 f
,所有文件對象方法都可以通過該變量訪問文件對象。read()
方法在第二行讀取整個文件,然后使用 print()
函數(shù)輸出文件內(nèi)容
當程序到達 with 語句塊上下文的末尾時,它會關(guān)閉文件以釋放資源并確保其他程序可以正常調(diào)用它們。通常當我們處理不再需要使用的,需要立即關(guān)閉的對象(例如文件、數(shù)據(jù)庫和網(wǎng)絡連接)時,強烈推薦使用 with 語句
這里需要注意的是,即使在退出 with 上下文管理器塊之后,我們也可以訪問 f
變量,但是該文件是已關(guān)閉狀態(tài)。讓我們嘗試一些文件對象屬性,看看變量是否仍然存在并且可以訪問:
print("Filename?is?'{}'.".format(f.name)) if?f.closed: ????print("File?is?closed.") else: ????print("File?isn't?closed.")
Output:
Filename is 'zen_of_python.txt'.
File is closed.
但是此時是不可能從文件中讀取內(nèi)容或?qū)懭胛募?,關(guān)閉文件時,任何訪問其內(nèi)容的嘗試都會導致以下錯誤:
f.read()
Output:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_9828/3059900045.py in <module>
----> 1 f.read()
ValueError: I/O operation on closed file.
Python 中的文件讀取模式
正如我們在前面提到的,我們需要在打開文件時指定模式。下表是 Python 中的不同的文件模式:
模式說明
- 'r' 打開一個只讀文件
- 'w' 打開一個文件進行寫入。如果文件存在,會覆蓋它,否則會創(chuàng)建一個新文件
- 'a' 打開一個僅用于追加的文件。如果該文件不存在,會創(chuàng)建該文件
- 'x' 創(chuàng)建一個新文件。如果文件存在,則失敗
- '+' 打開一個文件進行更新
我們還可以指定以文本模式“t”、默認模式或二進制模式“b”打開文件。讓我們看看如何使用簡單的語句復制圖像文件 dataquest_logo.png:
with?open('dataquest_logo.png',?'rb')?as?rf: ????with?open('data_quest_logo_copy.png',?'wb')?as?wf: ????????for?b?in?rf: ????????????wf.write(b)
上面的代碼復制 Dataquest 徽標圖像并將其存儲在同一路徑中。'rb' 模式以二進制模式打開文件并進行讀取,而 'wb' 模式以文本模式打開文件以并行寫入
讀取文本文件
在 Python 中有多種讀取文本文件的方法,下面我們介紹一些讀取文本文件內(nèi)容的有用方法
到目前為止,我們已經(jīng)了解到可以使用 read()
方法讀取文件的全部內(nèi)容。如果我們只想從文本文件中讀取幾個字節(jié)怎么辦,可以在 read()
方法中指定字節(jié)數(shù)。讓我們嘗試一下:
with?open('zen_of_python.txt')?as?f: ????print(f.read(17))
Output:
The Zen of Python
上面的簡單代碼讀取 zen_of_python.txt 文件的前 17 個字節(jié)并將它們打印出來
有時一次讀取一行文本文件的內(nèi)容更有意義,在這種情況下,我們可以使用 readline() 方法
with?open('zen_of_python.txt')?as?f: ????print(f.readline())
Output:
The Zen of Python, by Tim Peters
上面的代碼返回文件的第一行,如果我們再次調(diào)用該方法,它將返回文件中的第二行等,如下:
with?open('zen_of_python.txt')?as?f: ????print(f.readline()) ????print(f.readline()) ????print(f.readline()) ????print(f.readline())
Output:
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
這種有用的方法可以幫助我們以增量方式讀取整個文件。
以下代碼通過逐行迭代來輸出整個文件,直到跟蹤我們正在讀取或?qū)懭胛募奈恢玫奈募羔樀竭_文件末尾。當 readline()
方法到達文件末尾時,它返回一個空字符串
with?open('zen_of_python.txt')?as?f: ????line?=?f.readline() ????while?line: ????????print(line,?end='') ????????line?=?f.readline()
Output:
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
上面的代碼在 while
循環(huán)之外讀取文件的第一行并將其分配給 line
變量。在 while
循環(huán)中,它打印存儲在 line
變量中的字符串,然后讀取文件的下一行。while
循環(huán)迭代該過程,直到 readline()
方法返回一個空字符串??兆址?nbsp;while
循環(huán)中的計算結(jié)果為 False
,因此迭代過程終止
讀取文本文件的另一個有用方法是 readlines()
方法,將此方法應用于文件對象會返回包含文件每一行的字符串列表
with?open('zen_of_python.txt')?as?f: ????lines?=?f.readlines()
讓我們檢查 lines 變量的數(shù)據(jù)類型,然后打印它:
print(type(lines)) print(lines)
Output:
<class 'list'>
['The Zen of Python, by Tim Peters\n', '\n', 'Beaut...]
它是一個字符串列表,其中列表中的每個項目都是文本文件的一行,``\n` 轉(zhuǎn)義字符表示文件中的新行。此外,我們可以通過索引或切片操作訪問列表中的每個項目:
print(lines) print(lines[3:5]) print(lines[-1])
Output:
['The Zen of Python, by Tim Peters\n', '\n', 'Beautiful is better than ugly.\n', ... -- let's do more of those!"]
['Explicit is better than implicit.\n', 'Simple is better than complex.\n']
Namespaces are one honking great idea -- let's do more of those!
讀取 CSV 文件
到目前為止,我們已經(jīng)學會了如何使用常規(guī)文本文件。但是有時數(shù)據(jù)采用 CSV 格式,數(shù)據(jù)專業(yè)人員通常會檢索所需信息并操作 CSV 文件的內(nèi)容
接下來我們將使用 CSV 模塊,CSV 模塊提供了有用的方法來讀取存儲在 CSV 文件中的逗號分隔值。我們現(xiàn)在就嘗試一下
import?csv with?open('chocolate.csv')?as?f: ????reader?=?csv.reader(f,?delimiter=',') ????for?row?in?reader: ????????print(row)
Output:
['Company', 'Bean Origin or Bar Name', 'REF', 'Review Date', 'Cocoa Percent', 'Company Location', 'Rating', 'Bean Type', 'Country of Origin']
['A. Morin', 'Agua Grande', '1876', '2016', '63%', 'France', '3.75', 'Â\xa0', 'Sao Tome']
['A. Morin', 'Kpime', '1676', '2015', '70%', 'France', '2.75', 'Â\xa0', 'Togo']
['A. Morin', 'Atsane', '1676', '2015', '70%', 'France', '3', 'Â\xa0', 'Togo']
['A. Morin', 'Akata', '1680', '2015', '70%', 'France', '3.5', 'Â\xa0', 'Togo']
...
CSV 文件的每一行形成一個列表,其中每個項目都可以輕松的被訪問,如下所示:
import?csv with?open('chocolate.csv')?as?f: ????reader?=?csv.reader(f,?delimiter=',') ????for?row?in?reader: ????????print("The?{}?company?is?located?in?{}.".format(row[0],?row[5]))
Output:
The Company company is located in Company Location.
The A. Morin company is located in France.
The A. Morin company is located in France.
The A. Morin company is located in France.
The A. Morin company is located in France.
The Acalli company is located in U.S.A..
The Acalli company is located in U.S.A..
The Adi company is located in Fiji.
...
很多時候,使用列的名稱而不是使用它們的索引,這通常對專業(yè)人員來說更方便。在這種情況下,我們不使用 reader()
方法,而是使用返回字典對象集合的 DictReader()
方法
import?csv with?open('chocolate.csv')?as?f: ????dict_reader?=?csv.DictReader(f,?delimiter=',') ????for?row?in?dict_reader: ????????print("The?{}?company?is?located?in?{}.".format(row['Company'],?row['Company?Location']))
Output:
The A. Morin company is located in France.
The A. Morin company is located in France.
The A. Morin company is located in France.
The A. Morin company is located in France.
The Acalli company is located in U.S.A..
The Acalli company is located in U.S.A..
The Adi company is located in Fiji.
...
讀取 JSON 文件
我們主要用于存儲和交換數(shù)據(jù)的另一種流行文件格式是 JSON,JSON 代表 JavaScript Object Notation,允許我們使用逗號分隔的鍵值對存儲數(shù)據(jù)
接下來我們將加載一個 JSON 文件并將其作為 JSON 對象使用,而不是作為文本文件,為此我們需要導入 JSON 模塊。然后在 with
上下文管理器中,我們使用了屬于 json 對象的 load()
方法,它加載文件的內(nèi)容并將其作為字典存儲在上下文變量中。
import?json with?open('movie.json')?as?f: ????content?=?json.load(f) ????print(content)
Output:
{'Title': 'Bicentennial Man', 'Release Date': 'Dec 17 1999', 'MPAA Rating': 'PG', 'Running Time min': 132, 'Distributor': 'Walt Disney Pictures', 'Source': 'Based on Book/Short Story', 'Major Genre': 'Drama', 'Creative Type': 'Science Fiction', 'Director': 'Chris Columbus', 'Rotten Tomatoes Rating': 38, 'IMDB Rating': 6.4, 'IMDB Votes': 28827}
讓我們檢查內(nèi)容變量的數(shù)據(jù)類型:
print(type(content))
Output:
<class 'dict'>
它的數(shù)據(jù)類型是字典,因此我們可以方便的從中提取數(shù)據(jù)
print('{}?directed?by?{}'.format(content['Title'],?content['Director']))
Output:
Bicentennial Man directed by Chris Columbus
總結(jié)
今天我們討論了 Python 中的文件處理,重點是讀取文件的內(nèi)容。我們了解了 open()
內(nèi)置函數(shù)、with
上下文管理器,以及如何讀取文本、CSV 和 JSON 等常見文件類型。
以上就是一文搞懂Python讀取text,CSV,JSON文件的方法的詳細內(nèi)容,更多關(guān)于Python讀取文件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python基于scrapy采集數(shù)據(jù)時使用代理服務器的方法
這篇文章主要介紹了Python基于scrapy采集數(shù)據(jù)時使用代理服務器的方法,涉及Python使用代理服務器的技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-04-04有關(guān)wxpython pyqt內(nèi)存占用問題分析
一直覺得wxpython占用內(nèi)存比較多,在工作中寫的一些小程序應用,一對比其它的小程序,發(fā)現(xiàn)內(nèi)存相差確實有點大2014-06-06