日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python 文件处理、字符编码(二)

發布時間:2024/8/26 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 文件处理、字符编码(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

引子

1.問題:給你一個文件 "兼職白領學生空姐模特護士聯系方式.txt" ,如何查看內容?

答:

  • 安裝文本編輯器軟件
  • 選中右鍵,利用文本編輯器軟件打開
  • 查看 or 寫入
  • 保存,關閉
  • PS: 看到居然還有xxx的女朋友 或 美好的事物應該分享,默默的把xxx的女朋友電話也寫進去

    2.問題:文件在硬盤上是如何存儲?

    答:以某種編碼格式的 “010101010101001” 保存在硬盤上。

    3.問題:假定世上無文本編輯器軟件,如何使用Python對文件進行操作?

    答:請看下面

    Python處理文件

    文件操作分為讀、寫、修改,我們先從讀開始學習

    讀文件

    示例1:

    f = open(file='D:/工作日常/兼職白領學生空姐模特護士聯系方式.txt',mode='r',encoding='utf-8')data = f.read()f.close()

    上述操作語法解釋:

    file='D:/工作日常/兼職白領學生空姐模特護士聯系方式.txt' 表示文件路徑 mode='r' 表示只讀(可以修改為其他) encoding='utf-8' 表示將硬盤上的 0101010 按照utf-8的規則去“斷句”,再將“斷句”后的每一段0101010轉換成unicode的 01010101,unicode對照表中有01010101和字符的對應關系。 f.read() 表示讀取所有內容,內容是已經轉換完畢的字符串。 f.close() 表示關閉文件

    PS: 此處的encoding必須和文件在保存時設置的編碼一致,不然“斷句”會不準確從而造成亂碼。

    示例2:

    f = open(file='D:/工作日常/兼職白領學生空姐模特護士聯系方式.txt',mode='rb') data = f.read() f.close()

    上述操作語法解釋:

    file='D:/工作日常/兼職白領學生空姐模特護士聯系方式.txt' 表示文件路徑 mode='rb' 表示只讀(可以修改為其他) f.read() 表示讀取所有內容,內容是硬盤上原來以某種編碼保存的 010101010,即:某種編碼格式的字節類型 f.close() 表示關閉文件

    問:示例2和示例1的區別在哪?

    答:在于示例2打開文件時并未指定encoding,這是為何?是因為直接以rb模式打開了文件 ,rb是指二進制模式,數據讀到內存里直接是bytes格式,如果想內容,還需要手動decode,因此在文件打開階段,不需要指定編碼

    問:假如你不知道你要處理的文件是什么編碼可怎么辦呢?

    import chardetf = open('log',mode='rb') data = f.read() f.close()result = chardet.detect(open('log',mode='rb').read()) print(result)

    輸出:

    {'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

    注意:

    • 文件操作時,以 “r”或“rb” 模式打開,則只能讀,無法寫入;
    • 硬盤上保存的文件都是某種編碼的0101010,打開時需要注意:
      • rb,直接讀取文件保存時原生的0101010,在Python中用字節類型表示
      • r和encoding,讀取硬盤的0101010,并按照encoding指定的編碼格式進行斷句,再將“斷句”后的每一段0101010轉換成unicode的 010101010101,在Python中用字符串類型表示

    循環文件

    f = open("兼職白領學生空姐模特護士聯系方式.txt",'r',encoding="utf-8")for line in f:print(line)f.close()

    寫文件

    f = open(file='D:/工作日常/兼職白領學生空姐模特護士聯系方式.txt',mode='w',encoding='utf-8') f.write('北大本科美國留學一次50,微信號:xxxxx') f.close()

    上術操作語法解釋:

    file='D:/工作日常/兼職白領學生空姐模特護士聯系方式.txt' 表示文件路徑 mode='w' 表示只寫 encoding='utf-8' 將要寫入的unicode字符串編碼成utf-8格式 f.write(...) 表示寫入內容,寫入的內容是unicode字符串類型,內部會根據encoding轉換為制定編碼的 01101010101,即:字節類型 f.close()

    二進制寫

    f = open(file='D:/工作日常/兼職白領學生空姐模特護士聯系方式.txt',mode='wb') f.write('北大本科美國留學一次50,微信號:xxxxx'.encode('utf-8')) f.close()

    上述操作語法解釋:

    file='D:/工作日常/兼職白領學生空姐模特護士聯系方式.txt' 表示文件路徑 mode='wb' 表示只以2進制模式寫 f.write(...) 表示寫入內容,寫入的內容必須字節類型,即:是某種編碼格式的0101010 f.close()

    注意:

    文件操作時,以 “w”或“wb” 模式打開,則只能寫,并且在打開的同時會先將內容清空。

    寫入到硬盤上時,必須是某種編碼的0101010,打開時需要注意:

    • wb,寫入時需要直接傳入以某種編碼的0100101,即:字節類型
    • w 和 encoding,寫入時需要傳入unicode字符串,內部會根據encoding制定的編碼將unicode字符串轉換為該編碼的 010101010

    追加

    把內容追加到文件尾部

    f = open("兼職白領學生空姐模特護士聯系方式.txt",'a',encoding="gbk")f.write("\n杜姍姍 北京 167 49 13324523342") f.close()

    運行結果

    姓名 地區 身高 體重 電話 況詠蜜 北京 171 48 13651054608 ...... 岳妮妮 深圳 177 54 18835324553 賀婉萱 深圳 174 52 18933434452 葉梓萱 上海 171 49 18042432324 杜姍姍 北京 167 49 13324523342 #這行是添加的

    注意:

    文件操作時,以 “a”或“ab” 模式打開,則只能追加,即:在原來內容的尾部追加內容

    寫入到硬盤上時,必須是某種編碼的0101010,打開時需要注意:

    • ab,寫入時需要直接傳入以某種編碼的0100101,即:字節類型
    • a 和 encoding,寫入時需要傳入unicode字符串,內部會根據encoding制定的編碼將unicode字符串轉換為該編碼的 010101010

    讀寫模式

    打開模式只有只讀、只寫、只追加,難道沒有可以讀寫的操作嗎?當然有

    讀寫模式

    f = open("兼職白領學生空姐模特護士聯系方式.txt",'r+',encoding="gbk") data = f.read() #可以讀內容 print(data) f.write("\nblack girl 河北 167 50 13542342233") #可以寫 f.close()

    但上面的內容寫到哪個位置了呢?答案是追加到了最后面。

    那如果是我想添加到任意位置呢?答案是可以,又是不可以。。。。,為啥,一會就學

    寫讀模式

    f = open("兼職白領學生空姐模特護士聯系方式.txt",'w+',encoding="gbk") data = f.read() print(data)f.write("\nnewline 1哈哈") f.write("\nnewline 2哈哈") f.write("\nnewline 3哈哈") f.write("\nnewline 4哈哈")print("content",f.read())f.close()

    輸出

    #注意這是個空行, 是上面print(data)的結果,代表 根本 沒讀到內容 content #從這開始,讀到的是剛寫入的內容 newline 1哈哈 newline 2哈哈 newline 3哈哈 newline 4哈哈

    此時查看文件 內容 發現,里面只有4條newline..內容,之前的舊內容全沒了,事實代表,w+會先把文件清空,再寫新內容,相比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判斷文件是否可寫

    每個都舉例試一下。

    現在提出一個縈繞心頭的問題,文件內容是否可修改?當然可以,但需要套路

    修改文件

    嘗試直接以r+模式打開文件,默認會把新增的內容追加到文件最后面。但我想要的是修改中間的內容 ,怎么辦? 為什么會把內容添加到尾部呢?(最新測試r+會從頭覆蓋,測試代碼如下)

    f1 = open("luffy.txt",'w',encoding="utf-8")f1.write("[路飛學城]")f1.close()f = open("luffy.txt",'r+',encoding="utf-8")f.write("alex")f.close()

    我們已經學了seek,現在告訴你,之所以內容會追加到最后面,是因為,文件一打開,要寫的時候,光標會默認移到文件尾部,再開始寫。 現在我想修改中間部分,是不是seek(中間位置)再寫就可以了呢?

    f = open("兼職白領學生空姐模特護士聯系方式utf8.txt",'r+',encoding="utf-8")f.seek(6)f.write("[路飛學城]")f.close()

    執行沒報錯,開心,看輸出

    王心[路飛學城]9 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 13542342233

    確實從第3個字開始改的,但是我擦,好像我的[路飛學城] 把后面的內容覆蓋啦。。。。,這不是我想要的呀。。。

    問:為什么這樣子?

    這是硬盤的存儲原理導致的,當你把文件存到硬盤上,就在硬盤上劃了一塊空間,存數據,等你下次打開這個文件 ,seek到一個位置,每改一個字,就是把原來的覆蓋掉,如果要插入,是不可能的,因為后面的數據在硬盤上不會整體向后移。所以就出現 當前這個情況 ,你想插入,卻變成了會把舊內容覆蓋掉。

    問:但是人家word, vim 都可以修改文件 呀,你這不能修改算個什么玩意?

    我并沒說就不能修改了,你想修改當然可以,就是不要在硬盤上修改,把內容全部讀到內存里,數據在內存里可以隨便增刪改查,修改之后,把內容再全部寫回硬盤,把原來的數據全部覆蓋掉。vim word等各種文本編輯器都是這么干的。

    問:說的好像有道理,但你又沒看過word軟件的源碼,你憑什么這么篤定?

    哈哈,我不需要看源碼,硬盤 的存儲原理決定了word必須這么干 ,不信的話,還有個簡單的辦法來確認我說的,就是用word or vim讀一個編輯一個大文件 ,至少幾百MB的,你 會發現,加載過程會花個數十秒,這段時間干嘛了? cpu 去玩了?去上廁所啦? 當然不是,是在努力把數據 從硬盤上讀到內存里。

    問:但是文件如果特別大,比如5個GB,讀到內存,就一下子吃掉了5GB內存,好費資源呀,有沒有更好的辦法呢?

    如果不想占內存,只能用另外一種辦法啦,就是邊讀邊改, 什么意思? 不是不能改么?是不能改原文件 ,但你可以打開舊文件 的同時,生成一個新文件呀,邊從舊的里面一行行的讀,邊往新的一行行寫,遇到需要修改就改了再寫到新文件 ,這樣,在內存里一直只存一行內容。就不占內存了。 但這樣也有一個缺點,就是雖然不占內存 ,但是占硬盤,每次修改,都要生成一份新文件,雖然改完后,可以把舊的覆蓋掉,但在改的過程中,還是有2份數據 的。

    問:還有更好的方式 么?

    有完沒完? 沒了。

    占硬盤方式的文件修改代碼示例

    f_name = "兼職白領學生空姐模特護士聯系方式utf8.txt" f_new_name = "%s.new" % f_nameold_str = "喬亦菲" new_str = "[喬亦菲 Yifei Qiao]"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:new_line = line.replace(old_str,new_str)else:new_line = linef_new.write(new_line)f.close() f_new.close()

    上面的代碼,會生成一個修改后的新文件 ,原文件不動,若想覆蓋原文件

    import osf_name = "兼職白領學生空姐模特護士聯系方式utf8.txt" f_new_name = "%s.new" % f_nameold_str = "喬亦菲" new_str = "[喬亦菲 Yifei Qiao]"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:new_line = line.replace(old_str,new_str)else:new_line = linef_new.write(new_line)f.close() f_new.close()os.rename(f_new_name,f_name) #把新文件名字改成原文件 的名字,就把之前的覆蓋掉了,windows使用os.replace # 幫助文檔

    一 文件操作

    ?

    一 介紹

    ?

    計算機系統分為:計算機硬件,操作系統,應用程序三部分。

    ?

    我們用python或其他語言編寫的應用程序若想要把數據永久保存下來,必須要保存于硬盤中,這就涉及到應用程序要操作硬件,眾所周知,應用程序是無法直接操作硬件的,這就用到了操作系統。操作系統把復雜的硬件操作封裝成簡單的接口給用戶/應用程序使用,其中文件就是操作系統提供給應用程序來操作硬盤虛擬概念,用戶或應用程序通過操作文件,可以將自己的數據永久保存下來。

    ?

    有了文件的概念,我們無需再去考慮操作硬盤的細節,只需要關注操作文件的流程:

    ?

    #1. 打開文件,得到文件句柄并賦值給一個變量 #2. 通過句柄對文件進行操作 #3. 關閉文件

    ?

    二 在python中

    ?

    #1. 打開文件,得到文件句柄并賦值給一個變量 f=open('a.txt','r',encoding='utf-8') #默認打開模式就為r#2. 通過句柄對文件進行操作 data=f.read()#3. 關閉文件 f.close()

    ?

    三 f=open('a.txt','r')的過程分析

    ?

    #1、由應用程序向操作系統發起系統調用open(...)#2、操作系統打開該文件,并返回一個文件句柄給應用程序#3、應用程序將文件句柄賦值給變量f

    ?

    四 強調!!!

    ?

    #強調第一點:
    打開一個文件包含兩部分資源:操作系統級打開的文件+應用程序的變量。在操作完畢一個文件時,必須把與該文件的這兩部分資源一個不落地回收,回收方法為:
    1、f.close() #回收操作系統級打開的文件
    2、del f #回收應用程序級的變量

    其中del f一定要發生在f.close()之后,否則就會導致操作系統打開的文件還沒有關閉,白白占用資源,
    而python自動的垃圾回收機制決定了我們無需考慮del f,這就要求我們,在操作完畢文件后,一定要記住f.close()

    雖然我這么說,但是很多同學還是會很不要臉地忘記f.close(),對于這些不長腦子的同學,我們推薦傻瓜式操作方式:使用with關鍵字來幫我們管理上下文
    with open('a.txt','w') as f:
    pass

    with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
    data=read_f.read()
    write_f.write(data)

    強調第一點:資源回收

    ?

    #強調第二點: f=open(...)是由操作系統打開文件,那么如果我們沒有為open指定編碼,那么打開文件的默認編碼很明顯是操作系統說了算了,操作系統會用自己的默認編碼去打開文件,在windows下是gbk,在linux下是utf-8。 這就用到了上節課講的字符編碼的知識:若要保證不亂碼,文件以什么方式存的,就要以什么方式打開。f=open('a.txt','r',encoding='utf-8')

    五 python2中的file與open

    ?

    #首先在python3中操作文件只有一種選擇,那就是open()#而在python2中則有兩種方式:file()與open() 兩者都能夠打開文件,對文件進行操作,也具有相似的用法和參數,但是,這兩種文件打開方式有本質的區別,file為文件類,用file()來打開文件,相當于這是在構造文件類,而用open()打開文件,是用python的內建函數來操作,我們一般使用open()打開文件進行操作,而用file當做一個類型,比如type(f) is file

    二 打開文件的模式

    ?

    文件句柄 = open('文件路徑', '模式')

    ?

    模式可以是以下方式以及他們之間的組合:

    ?

    CharacterMeaning
    ‘r'open for reading (default)
    ‘w'open for writing, truncating the file first
    ‘a'open for writing, appending to the end of the file if it exists
    ‘b'binary mode
    ‘t'text mode (default)
    ‘+'open a disk file for updating (reading and writing)
    ‘U'universal newline mode (for backwards compatibility; should not be used in new code)

    ?

    #1. 打開文件的模式有(默認為文本模式): r ,只讀模式【默認模式,文件必須存在,不存在則拋出異?!?w,只寫模式【不可讀;不存在則創建;存在則清空內容】 a, 之追加寫模式【不可讀;不存在則創建;存在則只追加內容】#2. 對于非文本文件,我們只能使用b模式,"b"表示以字節的方式操作(而所有文件也都是以字節的形式存儲的,使用這種模式無需考慮文本文件的字符編碼、圖片文件的jgp格式、視頻文件的avi格式) rb wb ab 注:以b方式打開時,讀取到的內容是字節類型,寫入時也需要提供字節類型,不能指定編碼#3. 了解部分 "+" 表示可以同時讀寫某個文件 r+, 讀寫【可讀,可寫】 w+,寫讀【可讀,可寫】 a+, 寫讀【可讀,可寫】x, 只寫模式【不可讀;不存在則創建,存在則報錯】 x+ ,寫讀【可讀,可寫】 xb

    ?

    # 回車與換行的來龍去脈
    http://www.cnblogs.com/linhaifeng/articles/8477592.html

    # U模式
    'U' mode is deprecated and will raise an exception in future versions
    of Python. It has no effect in Python 3. Use newline to control
    universal newlines mode.

    # 總結:
    在python3中使用默認的newline=None即可,換行符無論何種平臺統一用\n即可

    了解U模式與換行符

    三 操作文件的方法

    ?

    #掌握 f.read() #讀取所有內容,光標移動到文件末尾 f.readline() #讀取一行內容,光標移動到第二行首部 f.readlines() #讀取每一行內容,存放于列表中f.write('1111\n222\n') #針對文本模式的寫,需要自己寫換行符 f.write('1111\n222\n'.encode('utf-8')) #針對b模式的寫,需要自己寫換行符 f.writelines(['333\n','444\n']) #文件模式 f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式#了解 f.readable() #文件是否可讀 f.writable() #文件是否可讀 f.closed #文件是否關閉 f.encoding #如果文件打開模式為b,則沒有該屬性 f.flush() #立刻將文件內容從內存刷到硬盤 f.name

    ?

    練習,利用b模式,編寫一個cp工具,要求如下:

    ?

      1. 既可以拷貝文本又可以拷貝視頻,圖片等文件

    ?

      2. 用戶一旦參數錯誤,打印命令的正確使用方法,如usage: cp source_file target_file

    ?

      提示:可以用import sys,然后用sys.argv獲取腳本后面跟的參數

    ?

    import sys
    if len(sys.argv) != 3:
    print('usage: cp source_file target_file')
    sys.exit()

    source_file,target_file=sys.argv[1],sys.argv[2]
    with open(source_file,'rb') as read_f,open(target_file,'wb') as write_f:
    for line in read_f:
    write_f.write(line)

    四 文件內光標移動

    ?

    一: read(3):

    ?

      1. 文件打開方式為文本模式時,代表讀取3個字符

    ?

      2. 文件打開方式為b模式時,代表讀取3個字節

    ?

    二: 其余的文件內光標移動都是以字節為單位如seek,tell,truncate

    ?

    注意:

    ?

      1. seek有三種移動方式0,1,2,其中1和2必須在b模式下進行,但無論哪種模式,都是以bytes為單位移動的

    ?

      2. truncate是截斷文件,所以文件的打開方式必須可寫,但是不能用w或w+等方式打開,因為那樣直接清空文件了,所以truncate要在r+或a或a+等模式下測試效果

    ?

    import time
    with open('test.txt','rb') as f:
    f.seek(0,2)
    while True:
    line=f.readline()
    if line:
    print(line.decode('utf-8'))
    else:
    time.sleep(0.2)

    練習:基于seek實現tail -f功能

    ?

    五 文件的修改

    ?

    文件的數據是存放于硬盤上的,因而只存在覆蓋、不存在修改這么一說,我們平時看到的修改文件,都是模擬出來的效果,具體的說有兩種實現方式:

    ?

    方式一:將硬盤存放的該文件的內容全部加載到內存,在內存中是可以修改的,修改完畢后,再由內存覆蓋到硬盤(word,vim,nodpad++等編輯器)

    ?

    import oswith open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:data=read_f.read() #全部讀入內存,如果文件很大,會很卡data=data.replace('alex','SB') #在內存中完成修改write_f.write(data) #一次性寫入新文件os.remove('a.txt') os.rename('.a.txt.swap','a.txt')?

    ?

    方式二:將硬盤存放的該文件的內容一行一行地讀入內存,修改完畢就寫入新文件,最后用新文件覆蓋源文件

    ?

    import oswith open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:for line in read_f:line=line.replace('alex','SB')write_f.write(line)os.remove('a.txt') os.rename('.a.txt.swap','a.txt')?

    ?

    練習題:

    ?

    1. 文件a.txt內容:每一行內容分別為商品名字,價錢,個數,求出本次購物花費的總錢數 apple 10 3 tesla 100000 1 mac 3000 2 lenovo 30000 3 chicken 10 32. 修改文件內容,把文件中的alex都替換成SB

    ?

    轉載于:https://www.cnblogs.com/xuan-xue/p/9486013.html

    總結

    以上是生活随笔為你收集整理的Python 文件处理、字符编码(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。