Python學習筆記系列之013:文件操作

来源:https://www.cnblogs.com/salmond/archive/2018/04/25/8926054.html
-Advertisement-
Play Games

一、文件的打開與關閉 1. 文件的打開 在python,使用open函數,可以打開一個已經存在的文件,或者創建一個新文件。 示例如下: f = open('test.txt', 'w') 2. 文件的關閉 示例如下: 註意:文件打開,執行必要的操作後必須要關閉。 但是我們總是經常忘記關閉它,怎麼辦呢 ...


 

一、文件的打開與關閉

1. 文件的打開

在python,使用open函數,可以打開一個已經存在的文件,或者創建一個新文件。

open(文件名,訪問模式)

示例如下:
f = open('test.txt', 'w')

2. 文件的關閉

示例如下:

# 新建一個文件,文件名為:test.txt
f = open('test.txt', 'w')

# 關閉這個文件
f.close()

註意:文件打開,執行必要的操作後必須要關閉。

但是我們總是經常忘記關閉它,怎麼辦呢?

3. 文件的另一種打開方式

with open(文件名, 訪問模式) as 別名:
    pass  # 對文件執行的操作

上述方法和以下代碼是等價的:

別名 = open(文件名, 訪問模式)
pass
別名.close()

 

由此可知,使用with方法訪問文件,就不必在手動close它,Python會自動把文件關閉掉,是不是很貼心?

二、文件的讀寫

1. 寫數據(write)

使用write()可以完成向文件寫入數據。
demo:

# 新建一個文件 file_write_test.py,向其中寫入如下代碼:
f = open('test.txt', 'w')
f.write('hello world, i am here!')
f.close()
# 運行之後會在file_write_test.py文件所在的路徑中創建一個文件test.txt,其中數據如下:
hello world, i am here!

註意:
如果文件不存在那麼創建,如果存在那麼就先清空,然後寫入數據。

2. 讀數據(read)

使用read(num)可以從文件中讀取數據,num表示要從文件中讀取的數據的長度(單位是位元組),如果沒有傳入num,那麼就表示讀取文件中所有的數據。
num大於數據長度時,不會報錯。讀完後,再讀的話,會得到''空字元串。
demo:

# 新建一個文件file_read_test.py,向其中寫入如下代碼:
f = open('test.txt', 'r')
content = f.read(5) # 最多讀取5個數據
print(content)
print("-"*30) # 分割線,用來測試
content = f.read() # 從上次讀取的位置繼續讀取剩下的所有的數據
print(content)
f.close() # 關閉文件,這個是個好習慣哦

# 運行現象:
hello
------------------------------
world, i am here!

註意:
如果用open打開文件時,如果使用的"r",那麼可以省略,即只寫 open('test.txt')

3. 讀數據(readlines)

就像read沒有參數時一樣,readlines可以按照行的方式把整個文件中的內容進行一次性讀取,並且返回的是一個列表,其中每一行的數據為一個元素。
讀完後,再讀的話,會得到[]空列表。

demo:

#coding=utf-8
f = open('test.txt', 'r')
content = f.readlines()
print(type(content))

i=1
for temp in content:
    print("%d:%s" % (i, temp))
    i += 1

f.close()

運行現象:
<class 'list'>
1:hello world, i am here!

<4>讀數據(readline)

一次讀一行。讀完後,再讀的話,會得到''空字元串。

#coding=utf-8
f = open('test.txt', 'r')

content = f.readline()
print("1:%s" % content)

content = f.readline()
print("2:%s" % content)

f.close()

運行現象:
1:hello world, i am here!
2:hello world, i am here!

想一想:
如果一個文件很大,比如5G,試想應該怎樣把文件的數據讀取到記憶體然後進行處理呢?

案例:製作文件的備份

任務描述:輸入文件的名字,然後程式自動完成對文件進行備份。

參考代碼:

 

# 獲取文件名
src_name = input('請輸入要備份的文件名:')

# 漂亮的目標文件名 aaa.bbb.txt
index = src_name.rfind('.')
dest_name = src_name[:index]+'[復件]' + src_name[index:]

# 打開文件
src_file = open(src_name, 'rb')
dest_file = open(dest_name, 'wb')

# 複製文件內容
while True:
    content = src_file.read(1024*8)   # 1024表示1024個位元組
    if len(content) == 0:
        break

dest_file.write(content)

# 關閉文件
src_file.close()
dest_file.close()

 

為什麼使用src_file.read(1024*8),而不是src_file.read()呢?因為如果文件很大的話,使用read()讀取會把記憶體撐爆。這時候使用以1024位元組單位迴圈讀取的話,就可以讀取大文件了。

三、文件的相關操作

有些時候,需要對文件進行重命名、刪除等一些操作,python的os模塊中都有這麼功能。
1. 文件重命名

os模塊中的rename()可以完成對文件的重命名操作。
rename(需要修改的文件名, 新的文件名)
import os
os.rename("畢業論文.txt", "畢業論文-最終版.txt")

2. 刪除文件
os模塊中的remove()可以完成對文件的刪除操作。
remove(待刪除的文件名)
import os
os.remove("畢業論文.txt")

3. 創建文件夾
import os
os.mkdir("張三")

4. 刪除文件夾
import os
os.rmdir("張三")

5. 獲取當前目錄
import os
os.getcwd()

6. 改變預設目錄
import os
os.chdir("../")

7. 獲取目錄列表
import os
os.listdir("./")

案例:批量修改文件名

需求:批量在文件名前加首碼

參考代碼:

#coding=utf-8
# 批量在文件名前加首碼
import os
funFlag = 1 # 1表示添加標誌 2表示刪除標誌
folderName = './renameDir/'

# 獲取指定路徑的所有文件名字
dirList = os.listdir(folderName)

# 遍歷輸出所有文件名字
for name in dirList:
    print(name)

    if funFlag == 1:
        newName = '[孟德出品]-' + name
    elif funFlag == 2:
        num = len('[孟德出品]-')
        newName = name[num:]
print(newName)

os.rename(folderName+name, folderName+newName)
View Code

 

四、編碼轉換

 

str->bytes:encode編碼
bytes->str:decode解碼
字元串通過編碼成為位元組碼,位元組碼通過解碼成為字元串。

>>> text = '我是文本'
>>> text
'我是文本'
>>> print(text)
我是文本
>>> bytesText = text.encode()
>>> bytesText
b'\xe6\x88\x91\xe6\x98\xaf\xe6\x96\x87\xe6\x9c\xac'
>>> print(bytesText)
b'\xe6\x88\x91\xe6\x98\xaf\xe6\x96\x87\xe6\x9c\xac'
>>> type(text)
<class 'str'>
>>> type(bytesText)
<class 'bytes'>
>>> textDecode = bytesText.decode()
>>> textDecode
'我是文本'
>>> print(textDecode)
我是文本

其中decode()與encode()方法可以接受參數,其聲明分別為:

bytes.decode(encoding="utf-8", errors="strict")
str.encode(encoding="utf-8", errors="strict")

其中的encoding是指在解碼編碼過程中使用的編碼(此處指“編碼方案”是名詞),errors是指錯誤的處理方案。
errors有兩個選項:

strict 表示嚴格按照指定的格式進行編碼解碼,如果編碼解碼不成功,則程式崩潰。
ignore 表示忽略編碼解碼不成功的字元,這樣代碼不會崩潰。

詳細的可以參照官方文檔:
str.encode()
bytes.decode()

五、綜合應用:學生管理系統 (文件版)

 需求就不說了,先把代碼運行一遍,看看效果,然後自己寫一個。

 

  1 import time
  2 import os
  3  
  4 # 定一個列表,用來存儲所有的學生信息(每個學生是一個字典)
  5 info_list = []
  6  
  7  
  8 def print_menu():
  9     print("---------------------------")
 10     print("      學生管理系統 V1.0")
 11     print(" 1:添加學生")
 12     print(" 2:刪除學生")
 13     print(" 3:修改學生")
 14     print(" 4:查詢學生")
 15     print(" 5:顯示所有學生")
 16     print(" 6:保存數據")
 17     print(" 7:退出系統")
 18     print("---------------------------")
 19  
 20  
 21 def add_new_info():
 22     """添加學生信息"""
 23     global info_list
 24  
 25     new_name = input("請輸入姓名:")
 26     new_tel = input("請輸入手機號:")
 27     new_qq = input("請輸入QQ:")
 28  
 29     for temp_info in info_list:
 30         if temp_info['name'] == new_name:
 31             print("此用戶名已經被占用,請重新輸入")
 32             return  # 如果一個函數只有return就相當於讓函數結束,沒有返回值
 33  
 34     # 定義一個字典,用來存儲用戶的學生信息(這是一個字典)
 35     info = {}
 36  
 37     # 向字典中添加數據
 38     info["name"] = new_name
 39     info["tel"] = new_tel
 40     info["qq"] = new_qq
 41  
 42     # 向列表中添加這個字典
 43     info_list.append(info)
 44  
 45  
 46 def del_info():
 47     """刪除學生信息"""
 48     global info_list
 49  
 50     del_num = int(input("請輸入要刪除的序號:"))
 51     if 0 <= del_num < len(info_list):
 52         del_flag = input("你確定要刪除麽?yes or no")
 53         if del_flag == "yes":
 54             del info_list[del_num]
 55     else:
 56         print("輸入序號有誤,請重新輸入")
 57  
 58  
 59 def modify_info():
 60     """修改學生信息"""
 61     global info_list
 62  
 63     modify_num = int(input("請輸入要修改的序號:"))
 64     if 0 <= modify_num < len(info_list):
 65         print("你要修改的信息是:")
 66         print("name:%s, tel:%s, QQ:%s" % (info_list[modify_num]['name'],
 67             info_list[modify_num]['tel'],info_list[modify_num]['qq']))
 68         info_list[modify_num]['name'] = input("請輸入新的姓名:")
 69         info_list[modify_num]['tel'] = input("請輸入新的手機號:")
 70         info_list[modify_num]['qq'] = input("請輸入新QQ:")
 71     else:
 72         print("輸入序號有誤,請重新輸入")
 73  
 74  
 75 def search_info():
 76     """查詢學生信息"""
 77     search_name = input("請輸入要查詢的學生姓名:")
 78     for temp_info in info_list:
 79         if temp_info['name'] == search_name:
 80             print("查詢到的信息如下:")
 81             print("name:%s, tel:%s, QQ:%s" % (temp_info['name'],
 82                 temp_info['tel'], temp_info['qq']))
 83             break
 84     else:
 85         print("沒有您要找的信息....")
 86  
 87  
 88 def print_all_info():
 89     """遍歷學生信息"""
 90     print("序號\t姓名\t\t手機號\t\tQQ")
 91     i = 0
 92     for temp in info_list:
 93         # temp是一個字典
 94         print("%d\t%s\t\t%s\t\t%s" % (i, temp['name'], temp['tel'], temp['qq']))
 95         i += 1
 96  
 97  
 98 def save_data():
 99     """載入之前存儲的數據"""
100     f = open("info_data.data", "w")
101     f.write(str(info_list))
102     f.close()
103  
104  
105 def load_data():
106     """載入之前存儲的數據"""
107     global info_list
108     f = open("info_data.data")
109     content = f.read()
110     info_list = eval(content)
111     f.close()
112  
113 def main():
114     """用來控制整個流程"""
115  
116     # 載入數據(1次即可)
117     load_data()
118  
119     while True:
120         # 1. 列印功能
121         print_menu()
122  
123         # 2. 獲取用戶的選擇
124         num = input("請輸入要進行的操作(數字):")
125  
126         # 3. 根據用戶選擇,做相應的事情
127         if num == "1":
128             # 添加學生
129             add_new_info()
130         elif num == "2":
131             # 刪除學生
132             del_info()
133         elif num == "3":
134             # 修改學生
135             modify_info()
136         elif num == "4":
137             # 查詢學生
138             search_info()
139         elif num == "5":
140             # 遍歷所有的信息
141             print_all_info()
142         elif num == "6":
143             # 保存數據到文件中
144             save_data()
145         elif num == "7":
146             # 退出系統
147             exit_flag = input("親,你確定要退出麽?~~~~(>_<)~~~~(yes or no) ")
148             if exit_flag == "yes":
149                 break
150         else:
151             print("輸入有誤,請重新輸入......")
152  
153  
154         input("\n\n\n按回車鍵繼續....")
155         os.system("clear")  # 調用Linux命令clear完成清屏
156  
157 # 程式的開始
158 main()
159  
160 註意:
161 以上程式,在運行之前請先建立info_data.data文件,並且寫入一對中括弧[]即可
162 等到後面講解完異常之後就解決了這個問題
163  
View Code

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • block 塊元素 inline 內聯元素 常見的塊元素有:div, p, h1~h6, table, form, ol, ul等 常見的內聯元素有:span, a, strong, em, label, input, select, textarea, img, br等 display:block ...
  • 場景: 我實際用到的是這樣的,我父組件引用子組件related,父組件調用獲取頁面詳情的方法,更新了state值related,子組件根據該related來渲染相關新聞內容,但是頁面打開的時候總是先載入子組件,子組件在渲染的時候還沒有獲取到更新之後的related值,即使在子組件中watch該值的變 ...
  • 主要是要引用$compile方法 ...
  • 看到小程式這一大串的“Do not have bindName handler in current page: pages/card/card. Please make sure that bindName handler has been defined in pages/card/card, ... ...
  • Qone 下一代 Web 查詢語言,使 javascript 支持 LINQ Github: "https://github.com/dntzhang/qone" 緣由 最近剛好修改了騰訊文檔 Excel 表格公式的一些 bug,主要是修改公式的 parser 。比如下麵的腳本怎麼轉成 javasc ...
  • 個人是這麼理解深拷貝和淺拷貝的:就是假設B複製了A,當修改A時,看B是否會發生變化,如果B也跟著變了,說明這是淺拷貝,拿人手短,如果B沒變,那就是深拷貝,自食其力。 一起看看我舉的淺拷貝慄子: 運行結果是:a數組元素跟著b數組改變 在來看看深拷貝的慄子 運行結果:a數組元素未隨b數組改變 ...
  • 圖片上傳 /static/img/H5_addPhoto.png" alt="picture"> /*圖片上傳*/ .photo - box { padding: 10 px; display: inline - block; } ... ...
  • 手把手教你寫網路爬蟲(6) 作者:拓海 摘要:從零開始寫爬蟲,初學者的速成指南! 封面: 下麵是一個超級電腦的排行榜,如果我們能擁有其中任意一個,那麼我們就不需要搞什麼分散式系統。可是我們買不起,即使買得起,也交不起電費,所以我們只好費腦子搞分散式。 Rank System Cores Rmax ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...