【Python 1-17】Python手把手教程之——文件的讀寫以及I/O操做

做者 | 弗拉德
來源 | 弗拉德(公衆號:fulade_me)python

從文件中讀取數據

文本文件可存儲的數據量不少,每當須要分析或修改存儲在文件中的信息時,讀取文件都頗有用,對數據分析應用程序來講尤爲 如此。例如,你能夠編寫一個這樣的程序:讀取一個文本文件的內容,從新設置這些數據的格式 並將其寫入文件,讓瀏覽器可以顯示這些內容。
要使用文本文件中的信息,首先須要將信息讀取到內存中。爲此,你能夠一次性讀取文件的所有內容,也能夠以每次一行的方式逐步讀取。git

讀取整個文件

要讀取文件,須要一個包含幾行文本的文件。下面首先來建立一個文件,它包含精確到小數點後30位的圓周率值,且在小數點後每10位處都換行:github

3.1415926535 
8979323846 
2643383279

咱們把它保存爲pi_digits.txt文件瀏覽器

with open('pi_digits.txt') as file_object: 
    contents = file_object.read() 
    print(contents)

咱們先來看看函數open()。要以任何方式使用文件——哪怕僅僅是打印其內容,都得先打開文件,這樣才能訪問它。函數open()接受一個參數: 要打開的文件的名稱。Python在當前執行的文件所在的目錄中查找指定的文件。在這個示例中,假如咱們把文件保存爲file_reader.py,所以Python在file_reader.py所在的目錄中查找pi_digits.txt。函數open()返回一個表示文件的對象。在這裏,open('pi_digits.txt')返回一個表示文件pi_digits.txt的對象,Python將這個對象存儲在咱們將在後面使用的變量中。
關鍵字with在再也不須要訪問文件後將其關閉。在這個程序中,注意到咱們調用了open(),但沒有調用close(),你也能夠調用open()close()來打開和關閉文件,但這樣作時,若是程序存在bug,致使close()語句未執行,文件將不會關閉。這看似微不足道,但未妥善地關閉文件可能會致使數據丟失或受損。若是在程序中過早地調用close(),你會發現須要使用文件時它已關閉,這會致使更多的錯誤。並不是在任何狀況下都能輕鬆肯定關閉文件的恰當時機,但經過使用前面所示的結構,可以讓Python去肯定:你只管打開文件,並在須要時使用它,Python自會在合適的時候自動將其關閉。
經過打印contents的值,就可將這個文本文件的所有內容顯示出來:bash

3.1415926535 
8979323846 
2643383279

文件路徑

當你將相似pi_digits.txt這樣的簡單文件名傳遞給函數open()時,Python將在當前執行的文件所在的目錄中查找文件。
根據你組織文件的方式,有時可能要打開不在程序文件所屬目錄中的文件。例如,你可能將 程序文件存儲在了文件夾python_work中,而在文件夾python_work中,有一個名爲text_files的文件夾,用於存儲程序文件操做的文本文件。雖然文件夾text_files包含在文件夾python_work中,但僅向open()傳遞位於該文件夾中的文件的名稱也不可行,由於Python只在文件夾python_work中查找,而不會在其子文件夾text_files中查找。要讓Python打開不與程序文件位於同一個目錄中的文件,須要提供文件路徑,它讓Python到系統的特定位置去查找。
因爲文件夾text_files位於文件夾python_work中,所以可以使用相對文件路徑來打開該文件夾中的文件。相對文件路徑讓Python到指定的位置去查找,而該位置是相對於當前運行的程序所在目錄的。在Linux和OS X中,你能夠這樣編寫代碼:閉包

with open('text_files/filename.txt') as file_object:

這行代碼讓Python到文件夾python_work下的文件夾text_files中去查找指定的.txt文件。在Windows系統中,在文件路徑中使用反斜槓\而不是斜槓/:app

with open('text_files\filename.txt') as file_object:

你還能夠將文件在計算機中的準確位置告訴Python,這樣就不用關心當前運行的程序存儲在什麼地方了。這稱爲絕對文件路徑。在相對路徑行不通時,可以使用絕對路徑。例如,若是text_files並不在文件夾python_work中,而在文件夾other_files中,則向open()傳遞路徑'text_files/ filename.txt'行不通,由於Python只在文件夾python_work中查找該位置。爲明確地指出你但願Python到哪裏去查找,你須要提供完整的路徑。
絕對路徑一般比相對路徑更長,所以將其存儲在一個變量中,再將該變量傳遞給open()會有所幫助。在Linux和OS X中,絕對路徑相似於下面這樣:編輯器

file_path = '/home/ehmatthes/other_files/text_files/filename.txt'
with open(file_path) as file_object:

而在Windows系統中,它們相似於下面這樣:函數

file_path = 'C:\Users\ehmatthes\other_files\text_files\filename.txt'
with open(file_path) as file_object:

經過使用絕對路徑,可讀取系統任何地方的文件。就目前而言,最簡單的作法是,要麼將 據文件存儲在程序文件所在的目錄,要麼將其存儲在程序文件所在目錄下的一個文件夾(如text_files)中。spa

逐行讀取

讀取文件時,經常須要檢查其中的每一行:你可能要在文件中查找特定的信息,或者要以某種方式修改文件中的文本。例如,你可能要遍歷一個包含天氣數據的文件,並使用天氣描述中包含字樣sunny的行。在新聞報道中,你可能會查找包含標籤<headline>的行,並按特定的格式設置它。
要以每次一行的方式檢查文件,可對文件對象使用for循環:

filename = 'pi_digits.txt'
with open(filename) as file_object: 
    for line in file_object:
    print(line)

咱們將要讀取的文件的名稱存儲在變量filename中,這是使用文件時一種常見的作法。因爲變量filename表示的並不是實際文件——它只是一個讓Python知道到哪裏去查找文件的字符串,所以可輕鬆地將'pi_digits.txt'替換爲你要使用的另外一個文件的名稱。

調用open()後,將一個表示文件及其內容的對象存儲到了變量file_object中。這裏也使用了關鍵字with,讓Python負責妥善地打開和關閉文件。爲查看文件的內容,咱們經過對文件對象執行循環來遍歷文件中的每一行,咱們打印每一行時,發現空白行更多了:

3.1415926535 

8979323846

2643383279

爲什麼會出現這些空白行呢?由於在這個文件中,每行的末尾都有一個看不見的換行符,而print語句也會加上一個換行符,所以每行末尾都有兩個換行符:一個來自文件,另外一個來自print語句。

建立一個包含文件各行內容的列表

使用關鍵字with時,open()返回的文件對象只在with代碼塊內可用。若是要在with代碼塊外訪問文件的內容,可在with代碼塊內將文件的各行存儲在一個列表中,並在with代碼塊外使用該列表:你能夠當即處理文件的各個部分,也可推遲到程序後面再處理。
下面的示例在with代碼塊中將文件pi_digits.txt的各行存儲在一個列表中,再在with代碼塊外打印它們:

filename = 'pi_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines() 
for line in lines:
    print(line.rstrip())

咱們先使用方法readlines()從文件中讀取每一行,並將其存儲在一個列表中接下來,該列表被存儲到變量lines中;在with代碼塊外,咱們依然可使用這個變量。咱們使用一個簡單的for循環來打印lines中的各行。因爲列表lines的每一個元素都對應於文件中的一行,所以輸出 與文件內容徹底一致。

使用文件的內容

將文件讀取到內存中後,就能夠以任何方式使用這些數據了。下面以簡單的方式使用圓周率 的值。首先,咱們將建立一個字符串,它包含文件中存儲的全部數字,且沒有任何空格:

filename = 'pi_digits.txt'
with open(filename) as file_object: 
    lines = file_object.readlines()
pi_string = '' 
for line in lines:
    pi_string += line.rstrip()
print(pi_string) 
print(len(pi_string))

就像前一個示例同樣,咱們首先打開文件,並將其中的全部行都存儲在一個列表中。咱們建立了一個變量——pi_string,用於存儲圓周率的值。接下來,咱們使用一個循環將各行都加入pi_string,並刪除每行末尾的換行符。接着,咱們打印這個字符串及其長度:

3.1415926535 8979323846 2643383279
36

在變量pi_string存儲的字符串中,包含原來位於每行左邊的空格,爲刪除這些空格,可以使用strip()而不是rstrip():

filename = 'pi_30_digits.txt'
with open(filename) as file_object: 
    lines = file_object.readlines()
pi_string = ''
for line in lines:
    pi_string += line.strip()
print(pi_string) 
print(len(pi_string))

這樣,咱們就得到了一個這樣的字符串:它包含精確到30位小數的圓周率值。這個字符串長32字符,由於它還包含整數部分的3和小數點:

3.141592653589793238462643383279
36

寫入文件

保存數據的最簡單的方式之一是將其寫入到文件中。經過將輸出寫入文件,即使關閉包含程 序輸出的終端窗口,這些輸出也依然存在:你能夠在程序結束運行後查看這些輸出,可與別人分享輸出文件,還可編寫程序來將這些輸出讀取到內存中並進行處理。

寫入空文件

要將文本寫入文件,你在調用open()時須要提供另外一個實參,告訴Python你要寫入打開的文 件。爲明白其中的工做原理,咱們來將一條簡單的消息存儲到文件中,而不是將其打印到屏幕上:

filename = 'programming.txt'
with open(filename, 'w') as file_object:
    file_object.write("I love programming.")

在這個示例中,調用open()時提供了兩個實參。第一個實參也是要打開的文件的名稱; 第二個實參w告訴Python,咱們要以寫入模式打開這個文件。打開文件時,可指定讀取模式r、寫入模式w、附加模式a或讓你可以讀取和寫入文件的模式r+。若是 你省略了模式實參,Python將以默認的只讀模式打開文件。

若是你要寫入的文件不存在,函數open()將自動建立它。然而,以寫入w模式打開文件時千萬要當心,由於若是指定的文件已經存在,Python將在返回文件對象前清空該文件。
咱們使用文件對象的方法write()將一個字符串寫入文件。這個程序沒有終端輸出,但若是你打開文件programming.txt,將看到其中包含以下一行內容:

I love programming.

相比於你的計算機中的其餘文件,這個文件沒有什麼不一樣。你能夠打開它、在其中輸入新文本、複製其內容、將內容粘貼到其中等。

寫入多行

函數write()不會在你寫入的文本末尾添加換行符,所以若是你寫入多行時沒有指定換行符,
文件看起來可能不是你但願的那樣:

filename = 'programming.txt'
with open(filename, 'w') as file_object:
    file_object.write("I love programming.") 
    file_object.write("I love creating new games.")

若是你打開programming.txt,將發現兩行內容擠在一塊兒:

I love programming.I love creating new games.

要讓每一個字符串都單獨佔一行,須要在write()語句中包含換行符:

filename = 'programming.txt'
with open(filename, 'w') as file_object:
    file_object.write("I love programming.\n") 
    file_object.write("I love creating new games\n")

如今,輸出出如今不一樣行中:

I love programming.
I love creating new games.

追加寫入文件

若是你要給文件添加內容,而不是覆蓋原有的內容,能夠附加模式打開文件。你以附加模式打開文件時,Python不會在返回文件對象前清空文件,而你寫入到文件的行都將添加到文件末尾。若是指定的文件不存在,Python將爲你建立一個空文件。

filename = 'programming.txt'
with open(filename, 'a') as file_object:
    file_object.write("I also love finding meaning in large datasets.\n")
    file_object.write("I love creating apps that can run in a browser.\n")

咱們打開文件時指定了實參a,以便將內容附加到文件末尾,而不是覆蓋文件原來的內容。而後,咱們又寫入了兩行,它們被添加到文件programming.txt末尾:

I love programming.
I love creating new games.
I also love finding meaning in large datasets.
I love creating apps that can run in a browser.

最終的結果是,文件原來的內容還在,它們後面是咱們剛添加的內容。 19

小做業
17-1 在文本編輯器中新建一個文件,寫幾句話來總結一下你至
此學到的Python知識。將這個文件命名爲 learning_python.txt,並將其存儲到爲完成本章練習而編寫的程序所在的目錄中。編寫一個程序,讀取整個文件,並打印。
17-2 訪客:編寫一個程序,提示用戶輸入其名字;用戶做出響應後,將其名字寫入到文件 guest.txt中。

想查看做業答案能夠去個人Githu倉庫在文件夾17-1_17-2


公衆號

相關文章
相關標籤/搜索