自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm=1001.2014.3001.5501
open()函數用于打開文件,返回一個文件讀寫對象,然后可以對文件進行相應讀寫操作。
????語法參考
open()函數的語法格式如下:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
參數說明:
l??file:必需參數,文件路徑,表示需要打開文件的相對路徑(相對于程序所在路徑,例如,要創建或打開程序所在路徑下的“mr.txt”文件,則可以直接寫成相對路徑“mr.txt”,如果是程序所在路徑下的“soft”子路徑下的“mr.txt”文件,則可寫成“soft/mr.txt”)或者絕對路徑(需要輸入包含盤符的完整文件路徑,如'D:/mr.txt')。文件路徑注意需要使用單引號或雙引號括起來。
多學兩招:在指定文件路徑時,也可以在表示路徑的字符串前面加上字母r(或R),那么該字符串將原樣輸出,這時路徑中的分隔符就不需要再轉義了。例如,路徑'D:/mr.txt'也可以寫作r'D:/mr.txt'。
l??mode:可選參數,用于指定文件的打開模式。常見的打開模式有r(以只讀模式打開)、w(以只寫模式打開)、a(以追加模式打開),默認的打開模式為只讀(即r)。實際調用的時候可以根據情況進行組合,mode參數的參數值及說明如表1所示。
表1? mode參數的參數值及說明
值 | 說????明 | 注????意 |
r | 以只讀模式打開文件(默認模式)。文件的指針將會放在文件的開頭 | 文件必須存在 |
rb | 以二進制格式打開文件,并且采用只讀模式。文件的指針將會放在文件的開頭。一般用于非文本文件,如圖片、聲音等 | |
r+ | 打開文件后,可以讀取文件內容,也可以寫入新的內容覆蓋原有內容(從文件開頭進行覆蓋) | |
rb+ | 以二進制格式打開文件,并且采用讀寫模式。文件的指針將會放在文件的開頭。一般用于非文本文件,如圖片、聲音等 | |
w | 以只寫模式打開文件。如果文件存在,則將其覆蓋;如果文件不存在,則創建新文件 | 必須要保證文件所在目錄存在,文件可以不存在 |
wb | 以二進制格式打開文件,并且采用只寫模式。一般用于非文本文件,如圖片、聲音等 | |
w+ | 打開文件后,先清空原有內容,使其變為一個空的文件,對這個空文件有讀寫權限 | |
wb+ | 以二進制格式打開文件,并且采用讀寫模式。一般用于非文本文件,如圖片、聲音等 | |
a | 以追加模式打開文件。如果文件存在,文件指針將放在文件的末尾(即新內容會被寫入到已有內容之后),如果文件不存在,則創建新文件用于寫入 | |
ab | 以二進制格式打開文件,并且采用追加模式。如果該文件已經存在,文件指針將放在文件的末尾(即新內容會被寫入到已有內容之后),否則,創建新文件用于寫入 | |
a+ | 以讀寫模式打開文件。如果該文件已經存在,文件指針將放在文件的末尾(即新內容會被寫入到已有內容之后),否則,創建新文件用于讀寫 | |
ab+ | 以二進制格式打開文件,并且采用追加模式。如果該文件已經存在,文件指針將放在文件的末尾(即新內容會被寫入到已有內容之后),否則,創建新文件用于讀寫 |
l??buffering:可選參數,用于指定讀寫文件的緩沖模式,值為0表示不緩存;值為1表示緩存(默認為緩存模式);如果大于1,則表示緩沖區的大小。
l??encoding:表示讀寫文件時所使用的文件編碼格式,一般使用UTF-8;
l??errors:表示讀寫文件時碰到錯誤的報錯級別。常見的報錯級別有:
???'strict':嚴格級別,字符編碼有報錯即拋出異常,默認級別,errors參數值傳入None即按此級別處理。
???'ignore':忽略級別,字符編碼有錯,忽略掉。
???'replace':替換級別,字符編碼有錯的,替換成?。
l??newline:表示用于區分換行符(只對文本模式有效,可以取的值有None、'\n'、'\r'、'\r\n')
l??closefd:表示傳入的file參數類型(缺省為True),傳入文件路徑時一定為True,傳入文件句柄則為False。
文件操作的常用方法
打開文件后對文件讀取操作通常有三種方法:read()方法表示讀取全部內容;readline()方法表示逐行讀取;readlines()方法表示讀取所有行內容。下面分別進行介紹。
l??read()方法
讀取文件的全部或部分內容,對于連續的面向行的讀取,則不使用該方法。語法如下:
fp.read([size])
其中,size為可選參數,用于指定要讀取文件內容的字符數(所有字符均按一個計算,包括漢字,如“name:無”的字符數為6),如read(8),表示讀取前8個字符。如果省略,則返回整個文件的內容。
注意:使用read()方法讀取文件內容時,如果文件大于可用內存,則不能實現文件的讀取,而是返回空字符串。
l??readline()方法
返回文件中一行的內容,具體語法為:
file.readline([size])
其中,size為可選參數,用于指定讀取一行內容的范圍,如readline(8),表示指讀取一行中前8個字符的內容。如果省略,則返回整行的內容。
l??readlines()方法
返回一個列表,列表中每個元素為文件中的一行數據,語法如下:
file.readlines()
除了對文件讀取操作,還可以對文件進行寫入、獲取文件指針位置和關閉文件等操作。具體方法如下:
l??write()方法
將內容寫入文件,語法如下:
f.write(obj)
其中,obj為要寫入的內容。
l??tell()方法
返回一個整數,表示文件指針的當前位置,即在二進制模式下距離文件頭的字節數,語法如下:
f.tell()
說明:使用tell()方法返回的位置與為read()方法指定的size參數不同。tell()方法返回的不是字符的個數,而是字節數,其中漢字所占的字節數根據其采用的編碼有所不同,如果采用GBK編碼,則一個漢字按兩個字符計算;如果采用UTF-8編碼,則一個漢字按3個字符計算。
l??seek()方法
將文件的指針移動到新的位置,位置通過字節數進行指定。這里的數值與tell()方法返回的數值的計算方法一致。語法如下:
file.seek(offset[,whence])
參數說明:
???file:表示已經打開的文件對象;
???offset:用于指定移動的字符個數,其具體位置與whence有關;
???whence:用于指定從什么位置開始計算。值為0表示從文件頭開始計算,1表示從當前位置開始計算,2表示從文件尾開始計算,默認為0。
l??close()方法
關閉打開的文件,語法如下:
f. close ()
????快用錦囊
錦囊01 ?常用文件讀取操作
打開文件后對文件讀取操作通常有三種方法:read()表示讀取全部內容;read(8)表示讀取前8個字符;readline()表示逐行讀取;readline(8)表示讀取行的前8個字符;readlines()表示讀取所有行內容,可以通過括號內的數字限制讀取內容的范圍。
l??一次讀取文件的全部內容
打開文件后,如果要一次讀取文件的全部內容,可以使用read()方法。代碼如下:
f =?open('D:/lift.txt')???????????????????#?以只寫模式打開文件
f.read()
使用readline()方法也可以實現文件全部內容的讀取,但括號中讀取的字符數要設置足夠大,實現代碼如下:
f =?open('D:/lift.txt')???????????????????#?以只寫模式打開文件
lines = f.readline(20000)??????????????#?設置讀取的字符足夠大
print(lines)???#?輸出讀取到的文件內容
f.close()??#?關閉文件
l??讀取文件或者每行的前幾個字符
如果要讀取文件內容中的前幾個字符,可以直接在Read()方法的括號里面輸入要讀取的字符數。如讀取文件的前8個字符,實現代碼如下:
f =?open('D:/lift.txt')???????????????????#?以只寫模式打開文件
f.read(8)
如果要一次讀取每行內容的前幾個字符,可以使用readline()方法,設置讀取的字符個數即可,實現代碼如下:
f =?open('D:/lift.txt')???????????????????#?以只寫模式打開文件
while True:
??? line = f.readline(5)??????????????#?一次讀取一行中的5個字符
????print(line)?? ?????????????????????#?輸出讀取的內容
????if?line ==?'': ???????????????????#?如果讀取的內容為空
????????break? ????????????????????????#?跳出循環
f.close() ????????????????????????????#?關閉文件
l??逐行讀取文件內容,可以使用while語句和readline()方法,實現代碼如下:
f =?open('D:/lift.txt')?????????#?以只寫模式打開文件
line = f.readline()?????????????#?讀取一行
while?line:
????print(line)?????????????????#?輸出讀取的一行內容
????line = f.readline()?????????#?讀取一行
f.close()???????????????????????#?關閉文件???
或
f =?open('D:/lift.txt')?????????#?以只寫模式打開文件
while True:
??? line = f.readline()?????????#?讀取一行
????print(line)?????????????????#?輸出讀取的一行內容
????if?line ==?'':??? ?????????#?如果讀取的內容為空
????????break???????????????????#?跳出循環
f.close()???????????????????????#?關閉文件
逐行讀取文件內容,也可以使用for語句和readline()方法,實現代碼如下:
for?line?in?open('D:/lift.txt'):
????print(line)???#?輸出一行內容
錦囊02 ?使用with open語句打開文件
在Python中,使用with open語句可以用指定的模式打開一個文件對象。使用該方式打開文件,并對文件操作完成后,無需通過close()方法關閉文件,文件會自動關閉。下面是一次讀取整個文件內容的代碼:
with?open('D:/lift.txt',?'r'?)?as?f:??#?以只讀方式打開文件
???print(f.read())???#?讀取全部文件內容并輸出
使用with open語句打開文件后,也可以按行讀取文件內容,代碼如下:
with?open('D:/lift.txt',?'r')?as?f:????????#?以只寫模式打開文件
????lines=f.readlines()?#?讀取全部內容
????for?line?in?lines:??#?遍歷每行內容
????????print(line.rstrip())??#?輸出每行中去掉右側空白字符的內容
錦囊03 ?在相對路徑下創建或寫入文件
編寫程序經常要用到絕對路徑和相對路徑,絕對路徑是指從根目錄開始直到文件所在位置的路徑,通常是從盤符開始的路徑,如“C:\mingribook\python”;相對路徑是程序或文件所在目錄到指定文件位置的路徑,如“/test”。使用相對路徑會使程序處理文件時非常靈活、方便。建議用戶在編寫程序時盡量使用相對路徑,除非特殊要求。本實例調用open()函數以寫方式打開程序所在路徑下的lift.txt文件,然后向該文件內寫入信息,示例代碼如下:
with?open('lift.txt',?'w')?as?f:????????#?以只寫模式打開文件
????f.write('生命美妙之處,?就在于你的勇氣會成就更美的你。')
執行上面的代碼后,將在程序所在路徑下生成一個名稱為lift.txtt的文件,內容如圖1所示。
圖1??創建的lift.txt文件
錦囊04 ?讀取操作文件時去除空格,空行等
讀取文件后,針對文件內容,有時需要做相應的處理,如去除空格、空行、回車符(\n)、制表符(\t)等。下面是數據去除的典型應用。
with?open('lift.txt',?'r')?as?f:????????#?以只讀模式打開文件
????for?line?in?f.readlines():
????????print( line.strip() )?????????#?去除空格
????????print( line.strip('\n') )?????#?去除換行符
????????print( line.strip('\t') )?????#?去除制表符
錦囊05 ?讀取非UTF-8編碼的文件
要讀取非UTF-8編碼的文本文件,需要給open()函數傳入encoding參數,例如,讀取GBK編碼的文件:
with?open('D:/lift.txt',?'r',encoding='gbk')?as?f:????????#?以只讀模式打開文件
print( f.readlines() )?????#?讀取全部內容
說明:在指定encoding參數時,指定的編碼一定是文件采用的編碼,否則將拋出異常。
讀取有些編碼不規范的文件,可能會出現UnicodeDecodeError錯誤,遇到這種情況,通過open()函數接收errors參數,在遇到編碼錯誤時,可以直接忽略錯誤,如:
with?open('D:/lift.txt',?'r',encoding='gbk',?errors='ignore')?as?f:???#?以只讀模式打開文件
????print( f.readlines() )?????#?讀取全部內容
錦囊06 ?在指定目錄(絕對路徑)下生成TXT文件
調用open()函數在D盤根目錄下創建一個名為lift.txt的文件,并且向該文件中寫入指定內容,示例代碼如下:
with?open('D:/lift.txt',?'w')?as?fp:??#?以只寫模式打開文件
????fp.write(' *'*10+'生命之美妙'+' *'*10)
??? fp.write('\n?????生命美妙之處,?就在于你的勇氣會成就更美的你。')
執行上面的代碼后,將在“D:\”目錄下生成一個名稱為lift.txtt的文件,內容如圖2示。
圖2?創建的lift.txt文件
錦囊07 ?以二進制方式打開圖片文件
在D盤目錄下放置一個名稱為python.jpg的圖片文件,如圖3示,使用open()函數以二進制方式打開該文件,并輸出創建的對象,示例代碼如下:
file =?open('D:/python.jpg','rb')????#?以二進制方式打開圖片文件
print(file)
運行上面的代碼,結果如下:
<_io.BufferedReader name='D:/python.png'>
圖3??目標圖片
錦囊08 ?多個文件的讀取操作
有時需要同時讀取多個文件的數據,如mr1.txt、mr2.txt、mr3.txt中的文件格式是一樣的,現在要分別從三個文件中讀取一行數據并輸出,實現代碼如下:
f1 =?open('mr1.txt',?'r')?????#?打開一個文件,命名為f1
f2 =?open('mr2.txt',?'r')?????#?打開一個文件,命名為f2
f3 =?open('mr3.txt',?'r')?????#?打開一個文件,命名為f3
i = f1.readline()????#?讀取一行
j = f2.readline()????#?讀取一行
k = f3.readline()????#?讀取一行
print(i, j, k) ??????#?輸出讀取到的數據
其實有更簡單的方法,使用zip()函數,代碼如下:
f1 =?open('mr1.txt',?'r')?????#?打開一個文件,命名為f1
f2 =?open('mr2.txt',?'r')?????#?打開一個文件,命名為f2
f3 =?open('mr3.txt',?'r')?????#?打開一個文件,命名為f3
for?i, j, k?in?zip(f1, f2, f3):??#?讀取每個文件的內容
????print(i, j, k)
錦囊09 ?讀取一個文件夾下所有文件
如果要讀取一個路徑下所有文件(不包含子文件夾下的文件),并將讀取的內容保存到一個列表進行輸出。需要遍歷該目錄下所有文件,然后循環讀取每個文件的內容到列表,最后將每個文件的內容添加到列表,實現代碼如下:
import?os???#?導入文件與系統操作模塊
path =?'temp/mr'?????????????#?待讀取文件的文件夾相對地址
names = os.listdir(path)????#?獲得目錄下所有文件的名稱列表
all = []????????????????????#?保存文件信息的列表
for?item?in?names:??????????#?讀取每一個文件
????f =?open(path+'/'+item)??#?打開文件
????new = []?????????????????#?保存單個文件內容的列表
????for?i?in?f:??????????????#?按行讀取文件內容
????????new.append(i)
??? all.append(new)??????????#將new添加到列表中
for?i?in?all:???#?遍歷并輸出列表
????print(i)
運行程序,程序所在目錄下包括3個文件,內容如圖4示。運行效果如下:
['生命美妙之處,?就在于你的勇氣會成就更美的你。\n']
["['明日學院', 'www.mingrisoft.com', '讓編程更簡單!']\n"]
['愿你的青春不負夢想!\n']
圖4?要讀取的3個文件的內容
錦囊10??將文件的寫入和讀取寫入類
自定義文件操作類operatxt,實現文件的寫入和讀取操作。示例代碼如下:
class?operatxt():??#?定義操作文件類
????def?__init__(self,encoding):
??????? self.enc = encoding
????def?WriteTxt(self,s):??#?寫入文件的方法
????????with?open("test.txt","a+",encoding=self.enc)?as?fileInfo:
??????????? fileInfo.write(s)???#?寫入內容
????def?ReadTxt(self):???#?讀取文件的方法
????????with?open("test.txt","r",encoding=self.enc)?as?fileInfo:
??????????? s= fileInfo.read()??#?讀取全部文件內容
????????????return?s
#?接收用戶輸入,將輸入內容寫入到文件,同時詢問用戶是讀取文件還是繼續寫入文件
#?當用戶選擇讀取文件時,將前面已經寫入的內容讀取出來并輸出給用戶,然后結束用戶輸入
while True:
??? content=input("請輸入要寫入到文件的內容:")
??? ot=operatxt("utf-8")??#?創建操作文件類的對象,指定編碼為UTF-8
????ot.WriteTxt(content)??#?寫入文件內容
????yn =?input("內容已寫入文件,是否要讀取?輸入y則讀取文件,繼續寫入請輸入n:")
????if?yn=='y':
??????? s=ot.ReadTxt()???#?讀取文件
????????print("文件內容為:",s)???#?輸出文件內容
????????break???#?退出出循環
輸出結果為:
請輸入要寫入到文件的內容:第一段:跟著你的心走。
內容已寫入文件,是否要讀取?輸入y則讀取文件,繼續寫入請輸入n:n
請輸入要寫入到文件的內容:第二段:You do what's in your heart.
內容已寫入文件,是否要讀取?輸入y則讀取文件,繼續寫入請輸入n:y
文件內容為:?第一段:跟著你的心走。第二段:You do what's in your heart.
運行程序,輸入需要寫入test.txt文件中的內容,然后在當前的Python文件的同級目錄下自動創建test.txt文件,內容如圖5所示。
圖5? test.txt文件的內容
????應用場景
場景一:逐行顯示螞蟻莊園的動態
在螞蟻莊園的動態欄目中記錄著莊園里的新鮮事,現在可以通過讀取文件的方式顯示莊園里的動態信息。首先應用open()函數以只讀方式打開一個記錄動態信息的文件,然后應用while語句創建一個循環,在該循環中調用readline()方法讀取一條動態信息并輸出,另外還需要判斷內容是否已經讀取完畢,如果讀取完畢應用break語句跳出循環,示例代碼如下:
print("\n","="*35,"螞蟻莊園動態","="*35,"\n")
with?open('message.txt','r')?as?file:???#?打開保存螞蟻莊園動態信息的文件
????number = 0???#?記錄行號
????while True:
??????? number += 1
??????? line = file.readline()
????????if?line =='':
????????????break????#?跳出循環
????????print(number,line,end=?"\n")??#?輸出一行內容
print("\n","="*39,"over","="*39,"\n")
輸出結果為:
===================================?螞蟻莊園動態?===================================
1?你使用了1張加速卡,小雞擼起袖子開始雙手吃飼料,進食速度大大加快。
2 mingri的小雞在你的莊園待了22分鐘,吃了6g飼料之后,被你趕走了。
3?你的小雞在QQ的莊園待了27分鐘,吃了8g飼料被莊園主人趕回來了。
4?你使用了1張加速卡,小雞擼起袖子開始雙手吃飼料,進食速度大大加快。
5 CC來到你的莊園,并提醒你無語的小雞已經偷吃飼料21分鐘,吃掉了6g。你的小雞拿出了10g飼料獎勵給CC。
?======================================= over =======================================
場景二:讀取兩層文件夾的文件內容
如果要讀取多層文件夾的所有文件內容,需要循環讀取各個文件夾的文件內容。讀取時,需要判斷讀取的是文件還是文件夾,如果是文件,先將文件的路徑和文件名稱保存到列表,然后讀取文件所有內容到列表;如果是文件夾,則循環讀取文件夾下的文件和文件夾,然后判斷是文件還是文件夾,如果是文件,仍然是先將文件的路徑和文件名稱保存到列表,然后讀取文件所有內容到列表。本實例只實現二級目錄的文件內容讀取,實現代碼如下:
import?os
path =?"user"???????#???要讀取的文件夾絕對路徑
import?os
list=[]??????????????????????#???保存文件內容的列表
path =?"user"?????????????#???讀取文件的目錄
files = os.listdir(path)?????#???目錄下所有文件和文件夾列表
for?file?in?files:??????? ???#???遍歷目錄下所有文件與文件夾
?? ???pathfile =path+"/"+file??#???帶完整路徑的文件或文件夾
?? ???if? not?os.path.isdir(pathfile):????? ????#?如果是文件(不是文件夾)
???? ??????with?open(pathfile,'r')?as?fp:??? ???#?只讀方式打開文件
?????????? ????list.append(pathfile)????????????#?添加文件路徑與名稱到列表
???????? ??????list.append(fp.readlines())??????#?將文件內容添加到列表
??? ??else:
?????????? newpath = path+"/"+file???????????????????#?指定下級目錄
?????? ????files1 = os.listdir(newpath)??????????????#?下級目錄下所有文件和文件夾列表
?????? ????for?file1?in?files1:??????????????????? ??# file1和files1不能寫成上層的file和files
????????? ?????pathfile = newpath +?"/"?+ file1??????#?帶完整路徑的下層文件或文件夾
?????????? ????if not?os.path.isdir(pathfile):???? ??#?如果是文件(不是文件夾)
????????????? ?????with?open(pathfile,?'r')?as?fp: ??#?只讀方式打開文件
????????????????? ?????list.append(pathfile)?????????#?添加文件路徑與名稱到列表
?????????????????? ????list.append(fp.readlines())???#?將文件內容添加到列表
? for?item?in?list:???????????????????????????? ?????#?遍歷列表
? ????print(item)
運行程序,實現效果如圖6所示。
圖6??輸出列表中保存的文件內容
注意:級聯目錄讀取時,下級級聯目錄是建立在上級目錄基礎上的,所以定義的上級目錄變量不能和下級目錄變量沖突。如代碼中的file、files是上級的目錄變量,file1、files1是下級目錄變量,兩者不能混淆。