第三章| 3.1文件处理
1、三元運算
簡單條件語句:
if 條件成立:val = 1
else: val = 2 改成三元運算:
val = 1 if 條件成立 else 2
2、文件處理 (用python對硬盤上的文件操作)
讀
讀取文件的三個方法:read()、readline()、readlines()
三個方法均可接受一個變量用以限制每次讀取的數據量,通常不使用該變量。
關于read()方法: 1、讀取整個文件,將文件內容放到一個字符串變量中 2、如果文件大于可用內存,不可能使用這種處理
關于readline()方法: 1、readline()每次讀取一行,比readlines()慢得多 2、readline()返回的是一個字符串對象,保存當前行的內容
關于readlines()方法: 1、一次性讀取整個文件。 2、自動將文件內容分析成一個行的列表。
?
f = open(file = "兼職白領學生空姐模特護士聯系方式.txt",mode="r",encoding="utf-8") #r模式以什么方式存的就要以什么方式讀出來。如果文件是gbk格式,就encoding=“gbk” data = f.read() #read方法是把文件全部讀出到屏幕輸出;readline是讀取文件的一行信息;readlines是讀取整個文件,輸出屏幕的是一行包含所有的信息。 print(data) f.close() #一定要加上這個,不然數據文件數據就沒有了,哎呀
read打印: 王心 北京 159 46 13813234424 馬纖羽 深圳 173 50 13744234523 喬亦菲 廣州 172 52 15823423525 羅夢竹 北京 175 49 18623423421 劉諾涵 北京 170 48 18623423765 岳妮妮 深圳 177 54 18835324553 賀婉萱 深圳 174 52 18933434452 葉梓萱 上海 171 49 18042432324 杜姍姍 北京 167 49 13324523342 black girl 河北 167 50 135423422334readline: 王心 北京 159 46 13813234424readlines: ['王心 北京 159 46 13813234424\n', '馬纖羽 深圳 173 50 13744234523\n', '喬亦菲 廣州 172 52 15823423525\n', '羅夢竹 北京 175 49 18623423421\n', '劉諾涵 北京 170 48 18623423765\n', '岳妮妮 深圳 177 54 18835324553\n', '賀婉萱 深圳 174 52 18933434452\n', '葉梓萱 上海 171 49 18042432324\n', '杜姍姍 北京 167 49 13324523342\n', 'black girl 河北 167 50 135423422334']
存在硬盤上是二進制。以什么方式存的文件,就要以什么樣的方式打開這個文件。此處的encoding必須和文件在保存時設置的編碼一致,不然“斷句”會不準確從而造成亂碼。
r文本模式, 二進制轉換為字符串。open把它轉一下。
rb為二進制模式,把這段內容直接讀到內存里邊來,硬盤怎么存的就怎么拿來,不用它轉了。 視頻、圖片或者網絡傳輸的文本,都是二進制模式。
f = open(file = "兼職白領學生空姐模特護士聯系方式.txt",mode="rb") #二進制模式就不需要encoding了 data = f.read() print(data) #打印出來就是二進制格式 f.close()
打印: b'\xe7\x8e\x8b\xe5\xbf\x83 \xe5\x8c\x97\xe4\xba\xac 159 46 13813234424\r\n\xe9\xa9\xac\xe7\xba\xa4\xe7\xbe\xbd \xe6\xb7\xb1\xe5\x9c\xb3 173 50 13744234523\r\n\xe4\xb9\x94\xe4\xba\xa6\xe8\x8f\xb2 \xe5\xb9\xbf\xe5\xb7\x9e 172 52 15823423525\r\n\xe7\xbd\x97\xe6\xa2\xa6\xe7\xab\xb9 \xe5\x8c\x97\xe4\xba\xac 175 49 18623423421\r\n\xe5\x88\x98\xe8\xaf\xba\xe6\xb6\xb5 \xe5\x8c\x97\xe4\xba\xac 170 48 18623423765\r\n\xe5\xb2\xb3\xe5\xa6\xae\xe5\xa6\xae \xe6\xb7\xb1\xe5\x9c\xb3 177 54 18835324553\r\n\xe8\xb4\xba\xe5\xa9\x89\xe8\x90\xb1 \xe6\xb7\xb1\xe5\x9c\xb3 174 52 18933434452\r\n\xe5\x8f\xb6\xe6\xa2\x93\xe8\x90\xb1 \xe4\xb8\x8a\xe6\xb5\xb7 171 49 18042432324\r\n\xe6\x9d\x9c\xe5\xa7\x97\xe5\xa7\x97 \xe5\x8c\x97\xe4\xba\xac 167 49 13324523342\r\nblack girl \xe6\xb2\xb3\xe5\x8c\x97 167 50 135423422334'
?
自動檢測編碼:(不知道原文件是什么編碼) import chardet f = open('log',mode='rb') data = f.read() f.close()result = chardet.detect(open('log',mode = 'rb').read()) print(result) #{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}
?
?循環文件 (邊讀邊處理,內存就存一小塊。)
f = open("兼職白領學生空姐模特護士聯系方式.txt",'r',encoding="gbk") for line in f:print(line) f.close()
#循環打印出:
王心 北京 159 46 13813234424馬纖羽 深圳 173 50 13744234523喬亦菲 廣州 172 52 15823423525羅夢竹 北京 175 49 18623423421劉諾涵 北京 170 48 18623423765岳妮妮 深圳 177 54 18835324553賀婉萱 深圳 174 52 18933434452葉梓萱 上海 171 49 18042432324杜姍姍 北京 167 49 13324523342black girl 河北 167 50 135423422334
?
寫文件(w是創建不是修改,沒有就清空覆蓋了。) ??w給轉換,而wb 二進制的就不用轉換了。
f = open("兼職.txt",'w',encoding = "gbk") #創建一個文件以gbk的形式 f.write(“路飛學城!”) #”路飛學城”是以unicode的形式寫的,再編碼為gbk f.close()
f = open("兼職2.txt",'wb') #創建一個兼職2的文件 f.write(“路飛學城!”.encode("gbk")) #encode下表示以什么樣的編碼存在 f.close()
f = open("兼職.txt",'wb') f.write("原子二號".encode("gbk")) #新寫進去的沒有的就清除再創建,會把原來的文件被清空了。 f.close()
?
追加模式(修改,追加到文件尾部。以a或者ab的模式打開)
f = open("兼職白領學生空姐模特護士聯系方式.txt",'ab') #以ab的模式打開 f.write("\n肛娘 北京 167 55 13312340322”.encode("gbk"))#追加到文件后面,\n為換行 f.close()
比如:追加“給歲月以文明,而不是給文明以歲月”在第五行。(就是把其他的內容往下擠,不是覆蓋第五行)(見練習題)
lines = [] f = open('三體語錄','r',encoding='utf-8') for line in f:lines.append(line) lines.insert(5,'給歲月以文明,而不是給文明以歲月\n') s = ''.join(lines) #把列表轉成字符串 with open('三體語錄','w',encoding='utf-8')as f_write:f_write.write(s)f_write.close()
?
混合操作(既能寫又能讀即 讀寫模式。r+ )
???
? 讀寫就相當于append,只是多了個可以讀。
寫讀模式 w+ ?(幾乎沒什么應用場景)
讀寫是先讀后寫,以讀的模式打開然后往后繼續追加;寫讀模式,是以寫的模式打開(就是創建的模式)支持你讀,把你寫的讀出來,但是之前的被清空了。
??
文件操作的其他功能
def fileno(self, *args, **kwargs): # real signature unknown返回文件句柄在內核中的索引值,以后做IO多路復用時可以用到def flush(self, *args, **kwargs): # real signature unknown把文件從內存buffer里強制刷新到硬盤def readable(self, *args, **kwargs): # real signature unknown判斷是否可讀def readline(self, *args, **kwargs): # real signature unknown只讀一行,遇到\r or \n為止def seek(self, *args, **kwargs): # real signature unknown把操作文件的光標移到指定位置*注意seek的長度是按字節算的, 字符編碼存每個字符所占的字節長度不一樣。如“路飛學城” 用gbk存是2個字節一個字,用utf-8就是3個字節,因此以gbk打開時,seek(4) 就把光標切換到了“飛”和“學”兩個字中間。但如果是utf8,seek(4)會導致,拿到了飛這個字的一部分字節,打印的話會報錯,因為處理剩下的文本時發現用utf8處理不了了,因為編碼對不上了。少了一個字節def seekable(self, *args, **kwargs): # real signature unknown判斷文件是否可進行seek操作def tell(self, *args, **kwargs): # real signature unknown返回當前文件操作光標位置 def truncate(self, *args, **kwargs): # real signature unknown按指定長度截斷文件*指定長度的話,就從文件開頭開始截斷指定長度,不指定長度的話,就從當前位置到文件尾部的內容全去掉。def writable(self, *args, **kwargs): # real signature unknown判斷文件是否可寫
?
flush 強制把內存刷到硬盤。
flush()?方法是用來刷新緩沖區的,即將緩沖區中的數據立刻寫入文件,同時清空緩沖區,不需要是被動的等待輸出緩沖區寫入,? ?正常情況下緩沖區滿時,操作系統會自動將緩沖數據寫入到文件中。
一般情況下,文件關閉后會自動刷新緩沖區,但有時你需要在關閉前刷新它,這時就可以使用 flush() 方法。
? ?至于close方法,原理是內部先調用flush方法來刷新緩沖區,再執行關閉操作,這樣即使緩沖區數據未滿也能保證數據的完整性。
???
readline()
?tell()返回當前文件操作光標位置; ?seek()把操作文件的光標移到指定位置。
????
seek(3)真的是字符嗎?不是的,seek是找的是字節。 ?tell()是尋找光標的位置 。read是讀的字符,tell和seek是找的字節。
utf-8中一個中文占3個字節,gbk中一個中文占2個字節。
>>>f = open('兼職白領學生空姐模特護士聯系方式.tex',‘r’, encoding='gbk') #文件里邊:hello world! >>>f.seek(3) 3 >>>f.readline() 'lo world!'
??
?
?truncate()按指定長度截斷文件?要以r+的模式打開???*指定長度的話,就從文件開頭開始截斷指定長度,不指定長度的話,就從當前位置到文件尾部的內容全去掉。
?
? ??
?文件修改 (兩種方式:要么占內存要么占硬盤)
?把光標seek到中間的位置就可以了。
占硬盤修改,打開舊文件一行行的讀,新文件一行行的寫。 ?最后把新文件重命名為舊文件,就把它覆蓋掉了。命名要 import os
import os
f_name = "兼職白領學生空姐模特護士聯系方式.txt" f_new_name = "%s.new" %f_nameold_str = "喬一菲" new_str = "紅娘"f = open(f_name,"r",encoding="utf-8") f_new = open(f_new_name,"w",encoding="utf-8")for line in f:if old_str in line:line = line.replace(old_str,new_str)f_new.write(line)f.close() f_new.close()os.rename(f_new_name,f_name)#把新文件名字改成原文件 的名字,就把之前的覆蓋掉了
占內存方式:以r+模式打開文件全read在內存,直接.replace,全程讀一遍然后再seek到文件開頭,再寫進去就覆蓋掉了。不一定能全部覆蓋,怎么辦:先把文件truncate完,flush
#占內存方式修改 f = open('兼職白領學生空姐模特護士聯系方式.txt','r+',encoding='utf-8') f1 = f.readlines() f.seek(0) #這個一定要加 old_str = "喬亦菲" new_str = "Yifei Qiao" for line in f1:if old_str in line:line = line.replace(old_str,new_str)f.write(line) #f.truncate() #f.flush() f.close() ################# f = open(r"info.txt", "r+") l = f.readlines() f.seek(0) # 指針指向文件開頭 old_str = "唐三" new_str = "" for line in l[0::2]: # 只取部分字符if old_str in line:line = line.replace(old_str,new_str)f.write(line+"\n") f.truncate() # 對文件進行截取,如果文件之前為100M, # 修改后文件只覆蓋了50M,如果不使用truncate不會整體覆蓋,只會部分覆蓋,后面剩余的50M內容會追加新文件中,修改后的文件大小不變 # 使用truncate后,文件就只有50M,他會把剩余的50M內容從當前write的指針后面進行截取 f.close()
?對文件的刪除
如:刪除最后一行
with open('三體語錄','r',encoding='utf-8') as f:f1 = f.readlines() ##readline 和readlines的區別with open('三體語錄','w',encoding='utf-8')as f_w:for line in f1:if '25' in line:continue #跳出本次循環f_w.write(line)
?
轉載于:https://www.cnblogs.com/shengyang17/p/8570312.html
總結
以上是生活随笔為你收集整理的第三章| 3.1文件处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个关于女王的个性签名。
- 下一篇: 经常可能会用到的【函数节流和函数防抖】记