天天看點

python将txt轉為字元串_Python檔案讀寫指南

python将txt轉為字元串_Python檔案讀寫指南

作者:豌豆花下貓,某985高校畢業生, 兼具極客思維與人文情懷 。公衆号【Python貓】, 專注python技術、資料科學和深度學習,力圖創造一個有趣又有用的學習分享平台。

對于初學者來說,一份詳盡又清晰明白的指南很重要。今天,貓貓跟大家一起,好好學習Python檔案讀寫的内容,這部分内容特别常用,掌握後對工作和實戰都大有益處。學習是循序漸進的過程,欲速則不達。文章較長,建議大家收藏,以備複習查閱哦。

1、如何将清單資料寫入檔案?

2、如何從檔案中讀取内容?

3、多樣需求的讀寫任務

4、從with語句到上下文管理器

如何将清單資料寫入檔案?

首先,我們來看看下面這段代碼,并思考:這段代碼有沒有問題,如果有問題的話,要怎麼改?

'python',
           

現在公布答案,這段代碼會報錯:

call 
           

以上代碼的想法是将list清單内容寫入txt檔案中,但是報錯 TypeError: write() argument must be str。就是說,write()方法必須接受字元串(str)類型的參數。

Python中内置了str()方法,可以傳回字元串版本的對象(Return a string version of object)。是以,上面的例子中,我們試試把 f.write(li) 改為 f.write(str(li)) ,先做一下字元串類型的轉化看看。代碼略。

這次沒有報錯了,但是打開檔案就傻眼了吧,寫入的内容是“['python',' is',' a',' cat']”。怎麼才能寫成“python is a cat”呢?

檔案寫操作還有一個writelines()方法,它接收的參數是由字元串組成的序列(sequence),實際寫入的效果是将全部字元串拼接在一起。字元串本身也是一種序列,是以當參數是字元串的時候,writelines()方法等價于write()。

3種寫法等價,都是寫入字元串“python 
           

由上可知,當多段分散的字元串存在于清單中的時候,要用writelines()方法,如果字元串是一整段,那直接使用write()方法。如果要以整個清單的形式寫入檔案,就使用str()方法做下轉化。

這個問題還沒結束,如果清單中就是有元素不是字元串,而且要把全部元素取出來,怎麼辦呢?

那就不能直接使用write()和writelines()了,需要先用for循環,把每個元素取出來,逐一str()處理。

In [
           

需要注意的是,writelines()不會自動換行。如果要實作清單元素間的換行,一個辦法是在每個元素後面加上換行符“\n”,如果不想改變元素,最好是用for循環,在寫入的時候加在末尾:for i in content:  f.writelines(str(i)+“\n”).

引申一下,經過實驗,數字及元祖類型也可以作為write()的參數,不需轉化。但是dict字典類型不可以,需要先用str()處理一下。字典類型比較特殊,最好是用json.dump()方法寫到檔案。

總結一下,write()接收字元串參數,适用于一次性将全部内容寫入檔案;writelines()接收參數是由字元串組成的序列,适用于将清單内容逐行寫入檔案。str()傳回Python對象的字元串版本,使用需注意。

如何從檔案中讀取内容?

從檔案中讀取内容有如下方法:

file.read([size])

從檔案讀取指定的位元組數,如果未給定或為負則讀取所有。

file.readline([size])

讀取整行,包括 "\n" 字元。

file.readlines([sizeint])

讀取所有行并傳回清單,若給定sizeint>0,則是設定一次讀多少位元組,這是為了減輕讀取壓力。

簡而言之,在不傳參數的情況下,read()對應write(),讀取全部内容;readlines()對應writelines(),讀取全部内容(含換行符)并以清單形式傳回,每個換行的内容作為清單的一個元素。

In [
           

但是,以上兩個方法有個缺點,當檔案過大的時候,一次性讀取太多内容,會對記憶體造成極大壓力。讀操作還有一個readline()方法,可以逐行讀取。

49]: 
           

readline()讀取第一行就傳回,再次調用f.readline(),會讀取下一行。

這麼看來,readline()太笨拙了。那麼,有什麼辦法可以優雅地讀取檔案内容呢?

回過頭來看readlines()方法,它傳回的是一個清單。這不奇怪麼,好端端的内容為啥要傳回成清單呢?

再想想writelines()方法,把字元串清單寫入檔案正是這家夥幹的事,readlines()方法恰恰是它的逆操作!而writelines()方法要配合for循環,是以我們把readlines()與for循環結合,看看會怎樣。

61]: 
           

總結一下,readline()比較雞肋,不咋用;read()适合讀取内容較少的情況,或者是需要一次性處理全部内容的情況;而readlines()用的較多,比較靈活,因為for循環是一種疊代器,每次加載部分内容,既減少記憶體壓力,又友善逐行對資料處理。

多樣需求的讀寫任務

前兩部分講了檔案讀寫的幾大核心方法,它們能夠起作用的前提就是,需要先打開一個檔案對象,因為隻有在檔案操作符的基礎上才可以進行讀或者寫的操作。

打開檔案用的是open()方法,是以我們再繼續講講這個方法。open() 方法用于打開一個檔案,并傳回檔案對象,在對檔案進行處理過程都需要使用到這個函數,如果該檔案無法被打開,會抛出 OSError。

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

open()方法的參數裡file(檔案)是必需的,其它參數最常用的是mode(模式)和encoding(編碼)。

先說說encoding,一般來說,打開檔案的編碼方式以作業系統的預設編碼為準,中文可能會出現亂碼,需要加encoding='utf-8'。

63]: 
           

再說mode,它指定檔案打開的模式。

'r': 以隻讀模式打開(預設模式,必須保證檔案存在)

'w':以隻寫模式打開。若檔案存在,則清空檔案,然後重新建立;若不存在,則建立

'a':以追加模式打開。若檔案存在,則會追加到檔案的末尾;若檔案不存在,則建立

常見的mode組合

'r'或'rt':   預設模式,文本讀模式

'w'或'wt':以文本寫模式打開(打開前檔案被清空)

'rb':       以二進制讀模式打開

'ab':      以二進制追加模式打開

'wb':      以二進制寫模式打開(打開前檔案被清空)

'r+':       以文本讀寫模式打開,預設寫的指針開始指在檔案開頭, 是以會覆寫檔案

'w+':      以文本讀寫模式打開(打開前檔案被清空)

'a+':      以文本讀寫模式打開(隻能寫在檔案末尾)

'rb+':     以二進制讀寫模式打開

'wb+':   以二進制讀寫模式打開(打開前被清空)

'ab+':    以二進制讀寫模式打開

喵喵,初看起來,模式很多,但是,它們隻是互相組合罷了。建議記住最基本的w、r、a,遇到特殊場景,再翻看一下就好了。

從with語句到上下文管理器

基礎部分講完了,下面是進階部分。知其然,更要知其是以然。

1、with語句是初學者必會常識

首先,要解釋一下為啥前文直接就用了with語句。with語句是讀寫檔案時的優雅寫法,這已經預設是Python初學者必會的常識了。如果你還不會,先看看用和不用with語句的對比:

# 不用with語句的正确寫法
           

因為檔案對象會占用作業系統的資源,并且作業系統同一時間能打開的檔案數量是有限的,是以open()方法之後一定要調用close()方法。另外,讀寫操作可能出現IO異常的情況,是以要加try…finally,保證無論如何,都會調用到close()方法。

這樣寫萬無一失,但是實在繁瑣,一不小心還可能漏寫或者寫錯。而with語句會保證調用close(),隻需一行代碼,簡直不要太優雅!是以,with語句是Python初學者必會技能。

2、什麼是上下文管理器?

下面,重頭戲來了,什麼是上下文管理器(context manager)?

上下文管理器是這樣一個對象:它定義程式運作時需要建立的上下文,處理程式的進入和退出,實作了上下文管理協定,即在對象中定義了 __enter__() 和 __exit__() 方法。

__enter__():進入運作時的上下文,傳回運作時上下文相關的對象,with 語句中會将這個傳回值綁定到目标對象。 

__exit__(exception_type, exception_value, traceback):退出運作時的上下文,定義在塊執行(或終止)之後上下文管理器應該做什麼。它可以處理異常、清理現場或者處理 with 塊中語句執行完成之後需要處理的動作。

注意enter和exit的前後有兩個下劃線,Python中自帶了很多類似的方法,它們是很神秘又很強大的存在,江湖人常常稱其為“黑魔法”。例如,疊代器協定就實作了__iter__方法。

在Python的内置類型中,很多類型都是支援上下文管理協定的,例如file,thread.LockType,threading.Lock等等。

上下文管理器無法獨立使用,它們要與with相結合,with語句可以在代碼塊運作前進入一個運作時上下文(執行_enter_方法),并在代碼塊結束後退出該上下文(執行__exit__方法)。

with 語句适用于對資源進行通路的場合,確定不管使用過程中是否發生異常都會執行必要的“清理”操作,釋放資源,比如檔案使用後自動關閉、線程中鎖的自動擷取和釋放等。

3、自定義上下文管理器

除了Python的内置類型,任何人都可以定義自己的上下文管理器。下面是一個示例:

class OpenFile(object):
           

最終寫入檔案的結果是:

enter now

Hello World!

exit now

上下文管理器必須同時提供 __enter__() 和 _exit_() 方法的定義,缺少任何一個都會導緻 AttributeError。 

上下文管理器在執行過程中可能會出現異常,_exit_() 的傳回值會決定異常的處理方式:傳回值等于 False,那麼這個異常将被重新抛出到上層;傳回值等于 True,那麼這個異常就被忽略,繼續執行後面的代碼。__exit()__ 有三個參數(exception_type, exception_value, traceback),即是異常的相關資訊。

4、contextlib實作上下文管理器

上例中,自定義上下文管理器的寫法還是挺繁瑣的,而且隻能用于類級别。為了更好地輔助上下文管理,Python 内置提供了 contextlib 子產品,進而可以很友善地實作函數級别的上下文管理器。

該子產品本質上是通過裝飾器(decorators)和生成器(generators)來實作上下文管理器,可以直接作用于函數/對象,而不用去關心 __enter__() 和 __exit()__ 方法的具體實作。

先把上面的例子改造一下,然後我們再對照着解釋:

from contextlib 
           

contextmanager是要使用的裝飾器,yield關鍵字将普通的函數變成了生成器。yield的傳回值(ff)等于上例__enter__()的傳回值,也就是as語句的值(f),而yield前後的内容,分别是_enter_() 和 _exit_() 方法裡的内容。

使用contextlib,可以避免類定義、_enter_() 和 __exit()__方法,但是需要我們捕捉可能的異常(例如,yield隻能傳回一個值,否則會導緻異常 RuntimeError),是以try…except語句不能忽略。

以上就是本文的全部内容,希望對大家的學習有所幫助。如果覺得文章不錯,動手轉發支援一下哦!

python将txt轉為字元串_Python檔案讀寫指南
python将txt轉為字元串_Python檔案讀寫指南
python将txt轉為字元串_Python檔案讀寫指南

感謝您的閱讀!想了解更多有關技巧,請關注我的微信公衆号“R語言和Python學堂”,我将定期更新相關文章。同時也歡迎大家積極投稿,促進交流。

我的專欄:

  • 簡書:https://www.jianshu.com/u/981ba7d6b4a6
  • 知乎:https://www.zhihu.com/people/zoro-3-92/activities