亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

給Python學(xué)習(xí)者的文件讀寫指南(含基礎(chǔ)與進(jìn)階)

 更新時(shí)間:2020年01月29日 20:33:58   作者:Python貓  
今天,貓貓跟大家一起,好好學(xué)習(xí)Python文件讀寫的內(nèi)容,這部分內(nèi)容特別常用,掌握后對工作和實(shí)戰(zhàn)都大有益處,學(xué)習(xí)是循序漸進(jìn)的過程,欲速則不達(dá)

對于初學(xué)者來說,一份詳盡又清晰明白的指南很重要。今天,貓貓跟大家一起,好好學(xué)習(xí)Python文件讀寫的內(nèi)容,這部分內(nèi)容特別常用,掌握后對工作和實(shí)戰(zhàn)都大有益處。學(xué)習(xí)是循序漸進(jìn)的過程,欲速則不達(dá)。文章較長,建議大家收藏,以備復(fù)習(xí)查閱哦。

1、如何將列表數(shù)據(jù)寫入文件?
2、如何從文件中讀取內(nèi)容?
3、多樣需求的讀寫任務(wù)
4、從with語句到上下文管理器

如何將列表數(shù)據(jù)寫入文件?

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

li = ['python',' is',' a',' cat']
with open('test.txt','w') as f:
  f.write(li)

現(xiàn)在公布答案,這段代碼會(huì)報(bào)錯(cuò):

TypeError  Traceback (most recent call last)
<ipython-input-6-57e0c2f5a453> in <module>()
      1 with open('test.txt','w') as f:
----> 2     f.write(li)

TypeError: write() argument must be str, not list

以上代碼的想法是將list列表內(nèi)容寫入txt文件中,但是報(bào)錯(cuò) TypeError: write() argument must be str。就是說,write()方法必須接受字符串(str)類型的參數(shù)。

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

這次沒有報(bào)錯(cuò)了,但是打開文件就傻眼了吧,寫入的內(nèi)容是“['python',' is',' a',' cat']”。怎么才能寫成“python is a cat”呢?

文件寫操作還有一個(gè)writelines()方法,它接收的參數(shù)是由字符串組成的序列(sequence),實(shí)際寫入的效果是將全部字符串拼接在一起。字符串本身也是一種序列,所以當(dāng)參數(shù)是字符串的時(shí)候,writelines()方法等價(jià)于write()。

# 以下3種寫法等價(jià),都是寫入字符串“python is a cat”
In [20]: with open('test.txt','w') as f:
  ...:   f.writelines(['python',' is',' a',' cat'])
  ...:   f.writelines('python is a cat')
  ...:   f.write('python is a cat')

# 以下2種寫法等價(jià),都是寫入列表的字符串版本“['python',' is',' a',' cat']”
In [21]: with open('test.txt','w') as f:
  ...:   f.write(str(['python',' is',' a',' cat']))
  ...:   f.writelines(str(['python',' is',' a',' cat']))

# 作為反例,以下寫法都是錯(cuò)誤的:
In [22]: with open('test.txt','w') as f:
  ...:   f.writelines([2018,'is','a','cat']) # 含非字符串
  ...:   f.write(['python','is','a','cat']) # 非字符串

由上可知,當(dāng)多段分散的字符串存在于列表中的時(shí)候,要用writelines()方法,如果字符串是一整段,那直接使用write()方法。如果要以整個(gè)列表的形式寫入文件,就使用str()方法做下轉(zhuǎn)化。

這個(gè)問題還沒結(jié)束,如果列表中就是有元素不是字符串,而且要把全部元素取出來,怎么辦呢?

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

In [37]: content=[1,' is',' everything']
In [38]: with open('test.txt','w') as f:
  ...:   for i in content:
  ...:     f.write(str(i))

需要注意的是,writelines()不會(huì)自動(dòng)換行。如果要實(shí)現(xiàn)列表元素間的換行,一個(gè)辦法是在每個(gè)元素后面加上換行符“\n”,如果不想改變元素,最好是用for循環(huán),在寫入的時(shí)候加在末尾:for i in content:  f.writelines(str(i)+“\n”).

引申一下,經(jīng)過實(shí)驗(yàn),數(shù)字及元祖類型也可以作為write()的參數(shù),不需轉(zhuǎn)化。但是dict字典類型不可以,需要先用str()處理一下。字典類型比較特殊,最好是用json.dump()方法寫到文件,具體操作方法以及注意事項(xiàng),請看喵喵之前發(fā)的《假期玩得開心也不忘充電,學(xué)習(xí)Python操作JSON,網(wǎng)絡(luò)數(shù)據(jù)交換不用愁》.

總結(jié)一下,write()接收字符串參數(shù),適用于一次性將全部內(nèi)容寫入文件;writelines()接收參數(shù)是由字符串組成的序列,適用于將列表內(nèi)容逐行寫入文件。str()返回Python對象的字符串版本,使用需注意。

如何從文件中讀取內(nèi)容?

從文件中讀取內(nèi)容有如下方法:

file.read([size])
從文件讀取指定的字節(jié)數(shù),如果未給定或?yàn)樨?fù)則讀取所有。

file.readline([size])
讀取整行,包括 "\n" 字符。

file.readlines([sizeint])
讀取所有行并返回列表,若給定sizeint>0,則是設(shè)置一次讀多少字節(jié),這是為了減輕讀取壓力。

簡而言之,在不傳參數(shù)的情況下,read()對應(yīng)write(),讀取全部內(nèi)容;readlines()對應(yīng)writelines(),讀取全部內(nèi)容(含換行符)并以列表形式返回,每個(gè)換行的內(nèi)容作為列表的一個(gè)元素。

In [47]: with open('test.txt','r') as f:
    ...:     print(f.read())
1 is everything.
python is a cat.
this is the end.

In [48]: with open('test.txt','r') as f:
    ...:     print(f.readlines())
['1 is everything.\n', 'python is a cat.\n', 'this is the end.']

但是,以上兩個(gè)方法有個(gè)缺點(diǎn),當(dāng)文件過大的時(shí)候,一次性讀取太多內(nèi)容,會(huì)對內(nèi)存造成極大壓力。讀操作還有一個(gè)readline()方法,可以逐行讀取。

In [49]: with open('test.txt','r') as f:
    ...:     print(f.readline())
1 is everything.

readline()讀取第一行就返回,再次調(diào)用f.readline(),會(huì)讀取下一行。

喵喵,是否感覺跟《超強(qiáng)匯總:學(xué)習(xí)Python列表,只需這篇文章就夠了》學(xué)習(xí)過的生成器很像,需要不停調(diào)用next()獲取下一行。

這么看來,readline()太笨拙了。那么,有什么辦法可以優(yōu)雅地讀取文件內(nèi)容呢?

回過頭來看readlines()方法,它返回的是一個(gè)列表。這不奇怪么,好端端的內(nèi)容為啥要返回成列表呢?

再想想writelines()方法,把字符串列表寫入文件正是這家伙干的事,readlines()方法恰恰是它的逆操作!而writelines()方法要配合for循環(huán),所以我們把readlines()與for循環(huán)結(jié)合,看看會(huì)怎樣。

In [61]: with open('test.txt','r') as f:
  ...:   for line in f.readlines():
  ...:     print(line)
1 is everything.

python is a cat.

this is the end.

# 讀取內(nèi)容包含換行符,所以要strip()去掉換行符
In [62]: with open('test.txt','r') as f:
  ...:   for line in f.readlines():
  ...:     print(line.strip())
1 is everything.
python is a cat.
this is the end.

總結(jié)一下,readline()比較雞肋,不咋用;read()適合讀取內(nèi)容較少的情況,或者是需要一次性處理全部內(nèi)容的情況;而readlines()用的較多,比較靈活,因?yàn)閒or循環(huán)是一種迭代器,每次加載部分內(nèi)容,既減少內(nèi)存壓力,又方便逐行對數(shù)據(jù)處理。

多樣需求的讀寫任務(wù)

前兩部分講了文件讀寫的幾大核心方法,它們能夠起作用的前提就是,需要先打開一個(gè)文件對象,因?yàn)橹挥性谖募僮鞣幕A(chǔ)上才可以進(jìn)行讀或者寫的操作。

打開文件用的是open()方法,所以我們再繼續(xù)講講這個(gè)方法。open() 方法用于打開一個(gè)文件,并返回文件對象,在對文件進(jìn)行處理過程都需要使用到這個(gè)函數(shù),如果該文件無法被打開,會(huì)拋出 OSError。

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

open()方法的參數(shù)里file(文件)是必需的,其它參數(shù)最常用的是mode(模式)和encoding(編碼)。

先說說encoding,一般來說,打開文件的編碼方式以操作系統(tǒng)的默認(rèn)編碼為準(zhǔn),中文可能會(huì)出現(xiàn)亂碼,需要加encoding='utf-8'。

In [63]: with open('test.txt','r') as f:
  ...:   for line in f.readlines():
  ...:     print(line.strip())
-----------------------
UnicodeDecodeError   Traceback (most recent call last)
<ipython-input-63-731a4f9cf707> in <module>()
   1 with open('test.txt','r') as f:
----> 2   for line in f.readlines():
   3     print(line.strip())
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa4 in position 26: illegal multibyte sequence

In [65]: with open('test.txt','r',encoding='utf-8') as f:
  ...:   for line in f.readlines():
  ...:     print(line.strip())
愛貓貓
python is a cat.

再說mode,它指定文件打開的模式。

'r': 以只讀模式打開(缺省模式,必須保證文件存在)
'w':以只寫模式打開。若文件存在,則清空文件,然后重新創(chuàng)建;若不存在,則新建
'a':以追加模式打開。若文件存在,則會(huì)追加到文件的末尾;若文件不存在,則新建


常見的mode組合
'r'或'rt': 默認(rèn)模式,文本讀模式
'w'或'wt':以文本寫模式打開(打開前文件被清空)
'rb': 以二進(jìn)制讀模式打開
'ab': 以二進(jìn)制追加模式打開
'wb': 以二進(jìn)制寫模式打開(打開前文件被清空)
'r+': 以文本讀寫模式打開,默認(rèn)寫的指針開始指在文件開頭, 因此會(huì)覆寫文件
'w+': 以文本讀寫模式打開(打開前文件被清空)
'a+': 以文本讀寫模式打開(只能寫在文件末尾)
'rb+': 以二進(jìn)制讀寫模式打開
'wb+': 以二進(jìn)制讀寫模式打開(打開前被清空)
'ab+': 以二進(jìn)制讀寫模式打開

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

從with語句到上下文管理器

基礎(chǔ)部分講完了,下面是進(jìn)階部分。知其然,更要知其所以然。

1、with語句是初學(xué)者必會(huì)常識

首先,要解釋一下為啥前文直接就用了with語句。with語句是讀寫文件時(shí)的優(yōu)雅寫法,這已經(jīng)默認(rèn)是Python初學(xué)者必會(huì)的常識了。如果你還不會(huì),先看看用和不用with語句的對比:

# 不用with語句的正確寫法
try:
  f = open('test.txt','w')
  f.writelines(['python',' is',' a',' cat'])
finally:
  if f:
    f.close()

# 使用with語句的正確寫法
with open('test.txt','w') as f:
  f.writelines(['python',' is',' a',' cat'])

因?yàn)槲募ο髸?huì)占用操作系統(tǒng)的資源,并且操作系統(tǒng)同一時(shí)間能打開的文件數(shù)量是有限的,所以open()方法之后一定要調(diào)用close()方法。另外,讀寫操作可能出現(xiàn)IO異常的情況,所以要加try…finally,保證無論如何,都會(huì)調(diào)用到close()方法。

這樣寫萬無一失,但是實(shí)在繁瑣,一不小心還可能漏寫或者寫錯(cuò)。而with語句會(huì)保證調(diào)用close(),只需一行代碼,簡直不要太優(yōu)雅!所以,with語句是Python初學(xué)者必會(huì)技能。

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

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

上下文管理器是這樣一個(gè)對象:它定義程序運(yùn)行時(shí)需要建立的上下文,處理程序的進(jìn)入和退出,實(shí)現(xiàn)了上下文管理協(xié)議,即在對象中定義了 __enter__() 和 __exit__() 方法。

__enter__():進(jìn)入運(yùn)行時(shí)的上下文,返回運(yùn)行時(shí)上下文相關(guān)的對象,with 語句中會(huì)將這個(gè)返回值綁定到目標(biāo)對象。

__exit__(exception_type, exception_value, traceback):退出運(yùn)行時(shí)的上下文,定義在塊執(zhí)行(或終止)之后上下文管理器應(yīng)該做什么。它可以處理異常、清理現(xiàn)場或者處理 with 塊中語句執(zhí)行完成之后需要處理的動(dòng)作。

注意enter和exit的前后有兩個(gè)下劃線,Python中自帶了很多類似的方法,它們是很神秘又很強(qiáng)大的存在,江湖人常常稱其為“黑魔法”。例如,迭代器協(xié)議就實(shí)現(xiàn)了__iter__方法。

在Python的內(nèi)置類型中,很多類型都是支持上下文管理協(xié)議的,例如file,thread.LockType,threading.Lock等等。

上下文管理器無法獨(dú)立使用,它們要與with相結(jié)合,with語句可以在代碼塊運(yùn)行前進(jìn)入一個(gè)運(yùn)行時(shí)上下文(執(zhí)行_enter_方法),并在代碼塊結(jié)束后退出該上下文(執(zhí)行__exit__方法)。

with 語句適用于對資源進(jìn)行訪問的場合,確保不管使用過程中是否發(fā)生異常都會(huì)執(zhí)行必要的“清理”操作,釋放資源,比如文件使用后自動(dòng)關(guān)閉、線程中鎖的自動(dòng)獲取和釋放等。

3、自定義上下文管理器

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

class OpenFile(object):
  def __init__(self,filename,mode):
    self.filename=filename
    self.mode=mode
  def __enter__(self):
    self.f=open(self.filename,self.mode)
    self.f.write("enter now\n")
    return self.f #作為as說明符指定的變量的值
  def __exit__(self,type,value,tb):
    self.f.write("exit now")
    self.f.close()
    return False  #異常會(huì)被傳遞出上下文
with OpenFile('test.txt','w') as f:
  f.write('Hello World!\n')

最終寫入文件的結(jié)果是:

enter now
Hello World!
exit now

上下文管理器必須同時(shí)提供 __enter__() 和 _exit_() 方法的定義,缺少任何一個(gè)都會(huì)導(dǎo)致 AttributeError。

上下文管理器在執(zhí)行過程中可能會(huì)出現(xiàn)異常,_exit_() 的返回值會(huì)決定異常的處理方式:返回值等于 False,那么這個(gè)異常將被重新拋出到上層;返回值等于 True,那么這個(gè)異常就被忽略,繼續(xù)執(zhí)行后面的代碼。__exit()__ 有三個(gè)參數(shù)(exception_type, exception_value, traceback),即是異常的相關(guān)信息。

4、contextlib實(shí)現(xiàn)上下文管理器

上例中,自定義上下文管理器的寫法還是挺繁瑣的,而且只能用于類級別。為了更好地輔助上下文管理,Python 內(nèi)置提供了 contextlib 模塊,進(jìn)而可以很方便地實(shí)現(xiàn)函數(shù)級別的上下文管理器。

該模塊本質(zhì)上是通過裝飾器(decorators)和生成器(generators)來實(shí)現(xiàn)上下文管理器,可以直接作用于函數(shù)/對象,而不用去關(guān)心 __enter__() 和 __exit()__ 方法的具體實(shí)現(xiàn)。

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

from contextlib import contextmanager

@contextmanager
def open_file(name):
  ff = open(name, 'w')
  ff.write("enter now\n")
  try:
    yield ff
  except RuntimeError:
    pass
  ff.write("exit now")
  ff.close()

with open_file('test.txt') as f:
  f.write('Hello World!\n')

contextmanager是要使用的裝飾器,yield關(guān)鍵字將普通的函數(shù)變成了生成器。yield的返回值(ff)等于上例__enter__()的返回值,也就是as語句的值(f),而yield前后的內(nèi)容,分別是_enter_() 和 _exit_() 方法里的內(nèi)容。

使用contextlib,可以避免類定義、_enter_() 和 __exit()__方法,但是需要我們捕捉可能的異常(例如,yield只能返回一個(gè)值,否則會(huì)導(dǎo)致異常 RuntimeError),所以try…except語句不能忽略。

喵喵喵,今天的分享就到這啦??垂賯?,覺得有用的話,分享給其他同樣好學(xué)的胖友們吧~~~~

相關(guān)文章

  • Pyecharts V1和V0.5之間相互切換的方法

    Pyecharts V1和V0.5之間相互切換的方法

    這篇文章主要介紹了Pyecharts V1和V0.5之間相互切換的方法,Pyecharts這個(gè)可視化庫火爆,官方如是說:Echarts 是一個(gè)由百度開源的數(shù)據(jù)可視化,憑借著良好的交互性,精巧的圖表設(shè)計(jì),得到了眾多開發(fā)者的認(rèn)可,下面和小編一起進(jìn)入文章了解具體內(nèi)容吧
    2022-02-02
  • 跟老齊學(xué)Python之print詳解

    跟老齊學(xué)Python之print詳解

    print的一些基本用法,在前面的講述中也涉及一些,本講是在復(fù)習(xí)的基礎(chǔ)上,盡量再多點(diǎn)內(nèi)容。
    2014-09-09
  • Python操作xlwings的實(shí)例詳解

    Python操作xlwings的實(shí)例詳解

    python操作Excel的模塊,網(wǎng)上提到的模塊大致有:xlwings、xlrd、xlwt、openpyxl、pyxll等。本文將通過幾個(gè)實(shí)例演示下xlwings的使用,感興趣的可以了解一下
    2022-07-07
  • python 畫出使用分類器得到的決策邊界

    python 畫出使用分類器得到的決策邊界

    這篇文章主要介紹了python 畫出使用分類器得到的決策邊界,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Python GUI編程學(xué)習(xí)筆記之tkinter事件綁定操作詳解

    Python GUI編程學(xué)習(xí)筆記之tkinter事件綁定操作詳解

    這篇文章主要介紹了Python GUI編程學(xué)習(xí)筆記之tkinter事件綁定操作,結(jié)合實(shí)例形式分析了Python GUI編程tkinter事件綁定常見操作技巧與使用注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • Python語言實(shí)現(xiàn)獲取主機(jī)名根據(jù)端口殺死進(jìn)程

    Python語言實(shí)現(xiàn)獲取主機(jī)名根據(jù)端口殺死進(jìn)程

    這篇文章主要介紹了Python語言實(shí)現(xiàn)獲取主機(jī)名根據(jù)端口殺死進(jìn)程的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • Python的歷史與優(yōu)缺點(diǎn)整理

    Python的歷史與優(yōu)缺點(diǎn)整理

    在本篇文章里小編給大家分享的是關(guān)于Python優(yōu)缺點(diǎn)及基礎(chǔ)知識點(diǎn)整理內(nèi)容,有需要的朋友們可以參考下。
    2020-05-05
  • 恢復(fù)百度云盤本地誤刪的文件腳本(簡單方法)

    恢復(fù)百度云盤本地誤刪的文件腳本(簡單方法)

    下面小編就為大家?guī)硪黄謴?fù)百度云盤本地誤刪的文件腳本(簡單方法)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • 如何通過雪花算法用Python實(shí)現(xiàn)一個(gè)簡單的發(fā)號器

    如何通過雪花算法用Python實(shí)現(xiàn)一個(gè)簡單的發(fā)號器

    這篇文章主要介紹了如何通過雪花算法用Python實(shí)現(xiàn)一個(gè)簡單的發(fā)號器,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • python利用線程生成不同尺寸的縮略圖實(shí)例詳解

    python利用線程生成不同尺寸的縮略圖實(shí)例詳解

    這篇文章主要介紹了python利用線程生成不同尺寸的縮略圖,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05

最新評論