簡介
文本文件和二進制文件
按文件中數據組織形式,我們把文件分爲文本文件和二進制文件兩大類:
1. 文本文件
文本文件存儲的是普通“字符”文本,python默認爲unicode字符集(兩個字節表示 一個字符,
最多可以表示:65536 個),可以使用記事本程序打開。但是,像word軟件編輯的文檔不是文
本文件。
2. 二進制文件
二進制文件把數據內容用“字節”進行存儲,無法用記事本打開。必須使用專用的軟件 解碼。
常見的有:MP4 視頻文件、MP3 音頻文件、JPG 圖片、doc 文檔等等。
文件操作相關模塊概述
創建文件對象 open()
open()函數用於創建文件對象,基本語法格式如下:
open(文件名[,打開方式])
如果只是文件名,代表在當前目錄下的文件。文件名可以錄入全路徑,比如:D:\a\b.txt。爲了減
少“\”的輸入,可以使用原始字符串:r“d:\b.txt”。示例如下: f = open(r"d:\b.txt","w")。
打開方式有如下幾種:
文本文件對象和二進制文件對象的創建:
如果我們沒有增加模式“b”,則默認創建的是文本文件對象,處理的基本單元是“字符”。如果是
二進制模式“b”,則創建的是二進制文件對象,處理的基本單元是“字節”。
一、文本文件的寫入
1、基本的文件寫入操作
文本文件的寫入一般就是三個步驟:
1. 創建文件對象
2. 寫入數據
3. 關閉文件對象
示例代碼:
# 文本寫入操作簡單測試
# 文本寫入操作簡單測試
file = open(r"E:\PythonProject\File_Test\file01.txt", "a")
info = '二哈撒的歡!!!'
file.write(info)
file.flush()
file.close()
2、常用編碼介紹
在操作文本文件時,經常會操作中文,這時候就經常會碰到亂碼問題。爲了解決中文亂碼問題,
這裏簡單介紹一下各種編碼之間的關係。
常用編碼之間的關係如下:
1. ASCII
全稱爲American Standard Code for Information Interchange,美國信息交換標準代碼,這是世界上
最早最通用的單字節編碼系統,主要用來顯示現代英語及其他西歐語言。 ASCII 碼用7位表示,只能表
示 128 個字符。只定義了2^7=128個字符,用7bit即可完全編碼,而一字節8bit的容量是256,所以一字
節ASCII 的編碼最高位總是0。
0~31 表示控制字符如回車、退格、刪除等;
32~126 表示打印字符即可以 通過鍵盤輸入並且能顯示出來的字符;
其中 48~57 爲0到9十個阿拉伯數字;
65~90 爲 26 個大寫英文字母;
97~122 號爲26個小寫英文字母;
其餘爲一些標點符號、運算符號等,具體可以參考 ASCII 標準表。
2. ISO8859-1
ISO-8859-1又稱Latin-1,是一個8位單字節字符集,它把ASCII的最高位也利用起來,併兼容了ASCII,
新增的空間是 128,但它並沒有完全用完。 在 ASCII 編碼之上又增加了西歐語言、希臘語、泰語、阿拉
伯語、希伯來語對應的文字符號,它是向下兼容 ASCII 編碼。
3. GB2312,GBK,GB18030
3.1:GB2312
GB2312 全稱爲信息交換用漢字編碼字符集,是中國於 1980 年發佈,主要用於計算機系統中的漢字
處理。GB2312 主要收錄了 6763 個漢字、682 個符號。 GB2312覆蓋了漢字的大部分使用率,但不能
處理像古漢語等特殊的罕用字, 所以後來出現了像GBK、GB18030 這種編碼。
**GB2312 完全兼容 ISO8859-1。**
3.2:GBK
全稱爲 Chinese Internal Code Specification,即漢字內碼擴展規範,於 1995 年制定。 它主要是
擴展了 GB2312,在它的基礎上又加了更多的漢字,它一共收錄了 21003 個漢字
3.3:GB18030
現在最新的內碼字集於 2000 年發佈,並於 2001 年強制執行,包含了中國大部分少數 民族的語言
字符,收錄漢字數超過 70000 餘個。 它主要採用單字節、雙字節、四字節對字符編碼,它是向下兼
容 GB2312 和 GBK 的, 雖然是我國的強制使用標準,但在實際生產中很少用到,用得最多的反而是
GBK 和 GB2312
3.4:Unicode
Unicode 編碼設計成了固定兩個字節,所有的字符都用16 位(2^16=65536) 表示,包括之前只佔8
位的英文字符等,所以會造成空間的浪費,UNICODE 在 很長的一段時間內都沒有得到推廣應用。
Unicode 完全重新設計,不兼容 iso8859-1,也不兼容任何其他編碼。
3.4:UTF-8
對於英文字母,unicode 也需要兩個字節來表示。所以 unicode 不便於傳輸和存儲。因此而產生
了UTF編碼,UTF-8 全稱是(8-bit Unicode Transformation Format)。 UTF編碼兼容iso8859-1編
碼,同時也可以用來表示所有語言的字符, 不過,UTF 編碼是不定長編碼,每一個字符的長度從
1-4 個字節不等。其中, 英文字母都是用一個字節表示,而漢字使用三個字節。
【老鳥建議】
一般項目都會使用 UTF-8。unicode 中雖然漢字是兩個字節, UTF-8 中漢字是 3 個字節。
但是互聯網中一個網頁也包含了大量的英文字母, 這些英文字母只佔用 1 個字節,整體佔用
空間,UTF-8 仍然由於 Unicode。
中文亂碼問題
windows 操作系統默認的編碼是 GBK,Linux操作系統默認的編碼是UTF-8。當我們用open()時,
調用的是操作系統打開的文件,默認的編碼是GBK。
3、write()/writelines()寫入數據
write(a):把字符串 a 寫入到文件中
writelines(b):把字符串列表寫入文件中,不添加換行符
示例代碼:
# 添加字符串列表數據到文件中
file = open(r"E:\PythonProject\File_Test\file01.txt", "a")
info = ['姓名\n', '年齡\n', '職業\n']
file.writelines(info)
file.flush()
file.close()
4、close()關閉文件流
由於文件底層是由操作系統控制,所以我們打開的文件對象必須顯式調用close()方法關閉文件
對象。當調用close()方法時,首先會把緩衝區數據寫入文件(也可以直接調用flush()方法),再關閉
文件,釋放文件對象。 爲了確保打開的文件對象正常關閉,一般結合異常機制的finally或者with關
鍵字實現無論何種情況都能關閉打開的文件對象。
示例代碼:
# 結合異常機制 finally 確保關閉文件對象
try:
file = open(r"E:\PythonProject\File_Test\file01.txt", "a")
info = ['姓名\n', '年齡\n', '職業\n']
file.writelines(info)
except BaseException as e:
print('異常信息:', e)
finally:
file.flush()
file.close()
# with 語句(上下文管理器)
# with 關鍵字(上下文管理器)可以自動管理上下文資源,不論什麼原因跳出with塊,都能確保
# 文件正確的關閉,並且可以在代碼塊執行完畢後自動還原進入該代碼塊時的現場。
# 使用 with 管理文件寫入操作
info2 = ['Jack\n', '20\n', 'IT\n']
with open(r"E:\PythonProject\File_Test\file01.txt", "a") as file2:
file2.writelines(info2)
二、文本文件的讀取
文件的讀取一般使用如下三個方法:
1. read([size])
從文件中讀取 size 個字符,並作爲結果返回。如果沒有 size 參數,則讀取整個文件。
讀取到文件末尾,會返回空字符串。
2. readline()
讀取一行內容作爲結果返回。讀取到文件末尾,會返回空字符串。
3. readlines()
文本文件中,每一行作爲一個字符串存入列表中,返回該列表
示例代碼:
'''源文件內容:
在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。
然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
這時就會打開Windows10的命令提示符窗口,在這裏可以輸入Dos命令
首先在命令後面輸入d:按下回後後就可以快速切換到D盤分區
然後可以使用cd bdjy的命令,回車後就可以進入bdjy的文件夾了。
'''
# 讀取文件的前幾個字符
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
print('讀取文件前幾個字符:', file.read(5))
# 文件較小,一次將文件內容讀入到程序中
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
print('讀取文件整個內容:\n', file.read())
# 按行讀取一個文件
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
while True:
file_line = file.readline()
if not file_line:
break
else:
print('讀取文件一行內容:', file_line, end="")
# 使用迭代器按行讀取一個文件
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
print('\n')
for file_line in file:
print('迭代器讀取文件一行內容:', file_line, end="")
# 爲文本文件每一行的行首增加一個行號
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
file_lines = file.readlines()
file_lines = [str(index + 1) + '. ' + line for index, line in enumerate(file_lines)]
with open(r"E:\PythonProject\File_Test\file01.txt", "w", encoding="GBK") as file:
file.writelines(file_lines)
====================運行結果================================
讀取文件前幾個字符: 在Wind
讀取文件整個內容:
在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。
然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
這時就會打開Windows10的命令提示符窗口,在這裏可以輸入Dos命令
首先在命令後面輸入d:按下回後後就可以快速切換到D盤分區
然後可以使用cd bdjy的命令,回車後就可以進入bdjy的文件夾了。
讀取文件一行內容: 在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。
讀取文件一行內容: 然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
讀取文件一行內容: 這時就會打開Windows10的命令提示符窗口,在這裏可以輸入Dos命令
讀取文件一行內容: 首先在命令後面輸入d:按下回後後就可以快速切換到D盤分區
讀取文件一行內容: 然後可以使用cd bdjy的命令,回車後就可以進入bdjy的文件夾了。
迭代器讀取文件一行內容: 在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。
迭代器讀取文件一行內容: 然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
迭代器讀取文件一行內容: 這時就會打開Windows10的命令提示符窗口,在這裏可以輸入Dos命令
迭代器讀取文件一行內容: 首先在命令後面輸入d:按下回後後就可以快速切換到D盤分區
迭代器讀取文件一行內容: 然後可以使用cd bdjy的命令,回車後就可以進入bdjy的文件夾了。
====================運行結果================================
三、二進制文件的讀取和寫入
二進制文件的處理流程和文本文件流程一致。首先還是要創建文件對象,不過,我們需要指
定二進制模式,從而創建出二進制文件對象。例如:
f = open(r"d:\a.txt", 'wb') #可寫的、重寫模式的二進制文件對象
f = open(r"d:\a.txt", 'ab') #可寫的、追加模式的二進制文件對象
f = open(r"d:\a.txt", 'rb') #可讀的二進制文件對象
創建好二進制文件對象後,仍然可以使用 write()、read()實現文件的讀寫操作。
示例代碼:
# 讀取文本文件,實現文件的拷貝
with open(r"E:\PythonProject\File_Test\file01.txt", "rb") as file:
with open(r"E:\PythonProject\File_Test\file01_bak.txt", "wb") as file2:
for line in file.readlines():
file2.write(line)
print('文件拷貝完成!!!')
四、文件對象的常用屬性和方法
文件對象的屬性
屬性 | 說明 |
---|---|
name | 返回文件的名字 |
mode | 返回文件的打開模式 |
closed | 若文件被關閉則返回 True |
文件對象的打開模式
模式 | 說明 |
---|---|
r | 讀模式 |
w | 寫模式 |
a | 追加模式 |
b | 二進制模式(可與其他模式組合) |
+ | 讀寫模式(可以其他模式組合) |
文件對象的常用方法
五、文件任意位置操作
seek()移動文件指針示例
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
print('文件名稱:{0}'.format(file.name))
print('文件指針的當前位置:', file.tell())
print('讀取的文件內容:{0}'.format(file.readline()))
print('文件指針的當前位置:', file.tell())
file.seek(83, 0)
print('讀取的內容:{0}'.format(file.readline()))
====================運行結果================================
文件名稱:E:\PythonProject\File_Test\file01.txt
文件指針的當前位置: 0
讀取的文件內容:1. 在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。
文件指針的當前位置: 83
讀取的內容:2. 然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
====================運行結果================================
六、使用 pickle 序列化
Python 中,一切皆對象,對象本質上就是一個“存儲數據的內存塊”。有時候,我們 需要將“內存
塊的數據”保存到硬盤上,或者通過網絡傳輸到其他的計算機上。這時候,就需要“對象的序列化和
反序列化”。 對象的序列化機制廣泛的應用在分佈式、並行系統上。
序列化指的是:將對象轉化成“串行化”數據形式,存儲到硬盤或通過網絡傳輸到其他 地方。
反序列化是指相反的過程,將讀取到的“串行化數據”轉化成對象。
我們可以使用 pickle 模塊中的函數,實現序列化和反序列操作。
**序列化使用:**
pickle.dump(obj, file) # obj 就是要被序列化的對象,file 指的是存儲的文件
pickle.load(file) # 從 file 讀取數據,反序列化成對象
示例代碼:
import pickle
# 將對象序列化到文件中
file_path = "E:\PythonProject\File_Test\\file01.txt"
with open(r"{0}".format(file_path), "wb") as file:
msg1 = 'Jack'
msg2 = '29'
msg3 = 'IT'
pickle.dump(msg1, file)
pickle.dump(msg2, file)
pickle.dump(msg3, file)
# 將獲得的數據反序列化成對象
with open(r"{0}".format(file_path), "rb") as file:
info1 = pickle.load(file)
info2 = pickle.load(file)
info3 = pickle.load(file)
print('{0} -- {1} -- {2}'.format(info1, info2, info3))
====================運行結果================================
Jack -- 29 -- IT
====================運行結果================================
七、CSV 文件的操作
csv(Comma Separated Values)是逗號分隔符文本格式,常用於數據交換、Excel 文件和數據庫數據
的導入和導出。與 Excel 文件不同,CSV 文件中:
值沒有類型,所有值都是字符串
不能指定字體顏色等樣式
不能指定單元格的寬高,
不能合併單元格
沒有多個工作表
不能嵌入圖像圖表
1、csv.reader 對象和 csv 文件讀取
示例代碼:
import csv
file_path = "E:\PythonProject\File_Test\\file02.csv"
with open(r"{0}".format(file_path)) as file:
csv_obj = csv.reader(file) # 創建csv對象,它是一個包含所有數據的列表,每一行爲一個元素
headers = next(csv_obj) # 獲得列表對象,包含標題行的信息
print("headers:", headers)
for row in csv_obj:
print("row:", row)
====================運行結果================================
headers: ['name', 'age', 'job', 'sex', 'salary']
row: ['Jack', '22', 'IT', '男', '8000']
row: ['Leo', '24', '銷售', '女', '5000']
row: ['Marry', '28', '經理', '女', '16000']
====================運行結果================================
2、csv.writer 對象和 csv 文件寫入
示例代碼:
import csv
file_path = "E:\PythonProject\File_Test\\file02.csv"
header_info = ['id', 'name', 'class', 'score', 'sex']
row1 = ['001', '張三', '3班', '99', '男']
row2 = ['014', '李四', '6班', '70', '女']
row3 = ['023', 'Jack', '4班', '58', '男']
row4 = [('006', 'Leo', '2班', '83', '女'),
('008', 'Amy', '1班', '83', '女'),
('016', 'Seven', '3班', '83', '女')]
# 加上newline=''數據之間不會有空行
with open(r"{0}".format(file_path), "w", newline='') as file:
csv_obj = csv.writer(file) # 創建CSV對象
csv_obj.writerow(header_info)
csv_obj.writerow(row1)
csv_obj.writerow(row2)
csv_obj.writerow(row3)
csv_obj.writerows(row4) # 寫入多行數據有加“s”的函數
八、os 和 os.path 模塊
os 模塊可以幫助我們直接對操作系統進行操作。我們可以直接調用操作系統的可執行 文件、命令,
直接操作文件、目錄等等。是系統運維的核心基礎。
1、os 模塊-調用操作系統命令
os.system 可以幫助我們直接調用系統的命令
【注】Linux 是命令行操作更容易,我們可以通過 os.system 可以更加容易的調用相關的命 令;
2、os 模塊-文件和目錄操作
os 模塊下常用操作文件的方法
os 模塊下關於目錄操作的相關方法,彙總如下:
3、os.path 模塊
os.path 模塊提供了目錄相關(路徑判斷、路徑切分、路徑連接、文件夾遍歷)的操作
4、walk()遞歸遍歷所有文件和目錄
os.walk()方法:
返回一個 3 個元素的元組:(dirpath, dirnames, filenames)
dirpath:要列出指定目錄的路徑
dirnames:目錄下的所有文件夾
filenames:目錄下的所有文件
5、shutil 模塊(拷貝和壓縮)
shutil模塊是python標準庫中提供的,主要用來做文件和文件夾的拷貝、移動、刪除等;
還可以做 文件和文件夾的壓縮、解壓縮操作。
os模塊提供了對目錄或文件的一般操作。
shutil 模塊作爲補充,提供了移動、複製、壓縮、解壓等操作,這些os模塊都沒有提供。
示例代碼:
import shutil
import zipfile
# copy文件內容
file_path = "E:\PythonProject\File_Test\\file02.csv"
file_path_bak = "E:\PythonProject\File_Test\\file02_bak.csv"
shutil.copy(file_path, file_path_bak)
# 實現遞歸的拷貝文件夾內容(使用 shutil 模塊)
file_dir = "E:\PythonProject\File_Test\學習文件"
new_dir = "E:\PythonProject\File_Test\\new_move"
# 此時new_move文件夾不存在時才成能功
shutil.copytree(file_dir, new_dir, ignore=shutil.ignore_patterns("*.csv"))
# 實現將文件夾所有內容壓縮(使用 shutil 模塊)
# 把“學習文件”壓縮到new_move文件夾下面(壓縮文件名:move.zip)
shutil.make_archive(new_dir + '\move', "zip", file_dir) # 注意參數位置信息
# 壓縮:將指定的多個文件壓縮到一個 zip 文件
zip = zipfile.ZipFile(new_dir + "\\new.zip", "w")
file1 = "E:\PythonProject\File_Test\學習文件\\file01.txt"
file2 = "E:\PythonProject\File_Test\學習文件\\file02.csv"
zip.write(file1)
zip.write(file2)
zip.close()
# 解壓縮
unzip = zipfile.ZipFile(new_dir + "\move.zip", "r")
unzip.extractall(new_dir + "\\new_zip") # 設置解壓的地址
unzip.close()
6、遞歸算法
遞歸是一種常見的解決問題的方法,即把問題逐漸簡單化。遞歸的基本思想就是“自己 調用自己”,
一個使用遞歸技術的方法將會直接或者間接的調用自己。 利用遞歸可以用簡單的程序來解決一些復
雜的問題。比如:斐波那契數列的計算、漢諾 塔、快排等問題。
遞歸結構包括兩個部分:
定義遞歸頭:
解答:什麼時候不調用自身方法。如果沒有頭,將陷入死循環,也就是遞歸的結束條件。
遞歸體:
解答:什麼時候需要調用自身方法。
學習來自:北京尚學堂高琪老師 Python 400集