12. 數據放在本地,心里才更踏實,滾雪球學 Python

如果你有想要交流的想法、技術,歡迎在評論區留言。

本篇文章要講解的內容是 Python 文件操作的相關內容,滾雪球學 Python 第一遍已經進行到中途,是否還能堅持住呢?加油。

已完成的文章

想學 Python 爬蟲,可以訂閱橡皮擦專欄哦~ ?????? 點擊發現驚喜 ??????

十二、Python 文件讀取與寫入

電腦文件的操作是任何一門編程語言都會涉及的知識,本篇博客主要圍繞 Windows 電腦上的文件操作進行說明,畢竟看到本博客內容的同學大多數都是使用的 Windows 電腦。

12.1 文件夾和文件路徑

文件和文件夾就不用說了吧,你想要學習編程肯定離不開電腦,對電腦文件和文件夾已經比較熟悉了,但是文件路徑可能就不太清楚了,本文開篇先介紹一下文件路徑相關問題。

2020120121283145[1].png

打開你的電腦上任一文件夾,在上圖所示位置發現的一個地址就是文件路徑,對于電腦上任一文件都可以用文件路徑+文件名訪問到。

C:\Users\Administrator\Desktop\書籍封面\abc.png

除了最后的是文件名以外,前面的就是文件路徑。
例如對于 abc.png 文件,它的文件路徑是 C:\Users\Administrator\Desktop\書籍封面。文件路徑可稱作文件目錄或者文件所在文件夾

12.1.1 絕對路徑和相對路徑

標題的這兩個概念很有意思,在第一次學習的時候很容易就弄迷糊了。
先記住絕對路徑吧,絕對就是絕對不變的意思。

例如上述文件 abc.png 它的絕對路徑就是硬盤上的一個不會變的地址,即 C:\Users\Administrator\Desktop\書籍封面 就是它的絕對路徑。

一般情況下理解為絕對路徑是從根目錄開始描述的路徑。

相對路徑,關鍵詞是相對,相對就是相對與當前目錄,這個需要結合案例進行學習,稍后補充。

還有兩個知識點需要補充一下。. 沒錯,就是一個點,表示的是當前文件夾;.. 兩個點表示的是上一層文件夾。

12.1.2 os 模塊與 os.path 模塊

在 Python 中操作文件路徑,使用 os 模塊,os.path 模塊是 os 模塊內部的一個子模塊,首先導入該模塊。

import os

獲取當前 Python 文件的目錄

getcwd 方法可以獲取當前 Python 文件所在的工作目錄,就是當前文件在那個文件夾中,獲取到的是絕對地址,例如下述代碼。

import os
print(os.getcwd())

**獲取絕對路徑 os.path.abspath **

os.path 模塊中的 abspath 方法可以返回絕對路徑,可以先通過 help 函數,查看該方法使用方式。

import os

help(os.path.abspath)

注意學習返回結果,學編程對英語要求不高,但是常見的單詞還是要認識一些的。

Help on function abspath in module ntpath:

abspath(path)
    Return the absolute version of a path.

abspath 方法需要一個參數 path,即一個路徑,基于該路徑在返回絕對路徑。

例如通過該代碼返回 demo4.py 文件的絕對路徑

import os

ret = os.path.abspath("demo4.py")
print(ret)

**獲取相對路徑 os.path.relpath **
絕對路徑返回的是一個從根目錄開始的路徑值,但是相對路徑不一樣,該方法既然叫做相對,那需要有一個相對對象,所以該方法的語法格式如下:

os.path.relpath(path,start)
  • path 就是要獲取絕對路徑的地址值,描述起來比較繞,一會看代碼;
  • start 相對的對象值。
import os

ret = os.path.relpath("D:\\")
print(ret)

獲取 D:\\ 該目錄的相對地址,相對于誰的地址,沒寫 start 參數就相對于當前工作目錄,即 Python 文件所在的目錄,你已經知道當前 Python 文件所在的目錄是 D:/gun/2

先認為的推斷一下 D:\\ 相對于 D:/gun/2 怎么獲取,應該是父級目錄的父級目錄,那用代碼怎么表示,已經學習了父級(上一層文件夾)目錄表示方式 ..,所以寫作 ..\.. ,整理完邏輯之后,發現跟代碼得到的效果一致。

..\..

path 參數修改為跟 Python 文件目錄一致的值,看一下是不是得到相對路徑是一個 .,表示當前目錄。

import os

ret = os.path.relpath("d:\\gun\\2")
# 或者寫成下面這個樣子
# ret = os.path.relpath("d:/gun/2")
print(ret)

結果輸出為 . ,沒錯是期望值。

學起來如果吃力,不要急,接著往下看,慢慢你就悟了。

12.1.3 路徑檢查方法

檢查路徑主要是為了檢查文件或者文件夾是否存在,或者判斷一個路徑對應的是一個文件夾還是一個文件。

  • exists(path) 如果 path 文件或文件夾存在返回 True,否則返回 False;
  • isabs(path) path 是絕對路徑返回 True,否則返回 False;
  • isdir(path) path 是文件夾返回 True,否則你懂;
  • isfile(path) path 是文件返回 True。

以上四個方法都在 os.path 模塊下,具體代碼比較簡單,自己嘗試一下即可。

12.1.4 目錄操作

以下幾個方法在 os 模塊中,執行如下操作建議先通過 os.path.exists 判斷目錄是否存在。

  • mkdir(path) 創建目錄;
  • rmdir(path) 刪除目錄;
  • chdir(path) 切換當前工作目錄到 path;
  • remove(path) 刪除文件,注意如果 path 是一個目錄,刪除會報錯,權限不足,刪除目錄請使用 rmdir

以上四個方法實際編碼也非常簡單,導入模塊之后,用就完了,橡皮擦自己就先不浪費篇幅了。

12.1.5 獲取文件大小

該內容只需要調用 getsize 方法即可。

import os
print(os.path.getsize("demo4.py"))

注意得到的是字節大小。

12.1.6 獲取指定目錄下面的所有內容

通過 os.listdir 方法可以獲取指定目錄下的所有內容,包括文件與文件夾。

import os
print(os.listdir("."))

輸出的內容:

['demo1.py', 'demo2.py', 'demo3.py', 'demo4.py', 'demo5.py', 'dog_module.py', '__pycache__']

可以與文件進行一下比對。

20201201221106724[1].png

12.1.7 os.walk 方法

這個方法比較不好理解,第一次滾雪球階段還是暫時略過,該方法可以遍歷目錄樹,通過循環就可以獲取到指定目錄下面所有的文件與文件夾了,但是咱不學 (^_?)☆

12.2 Python 讀寫文件

12.2.1 讀取文件

Python 在讀寫文件的時候首先要做的是打開文件,然后可以一次性讀取文件或者一行行的讀取,打開文件使用 open 函數。

讀取文件所有內容

使用 open 函數打開文件之后,可以通過 read 讀取文件內容,該方法相當于將文件的內容一次性的讀取到了程序的一個字符串中,非常強大。

test.txt 文件內容

夢想橡皮擦
是一個大佬
真的是一個大佬
我自己都信了

讀取代碼如下:

# 文件地址,注意提前在當前目錄新建一個 test.txt 文件
file = "test.txt"
# 打開文件
f = open(file, encoding="utf-8")
# 讀取文件全部內容
read_str = f.read()
# 關閉文件
f.close()
print(read_str)

第一點需要注意的是使用 open 打開文件時,必須在文件使用完畢之后通過 close 關閉文件。
第二點需要注意,上述代碼中 file = "test.txt" 該文件名并不是一個完整的路徑,這種情況下表示該文件和當前的 Python 文件在一個目錄,如果在不同目錄,需要用到前文講到的路徑相關知識了。

例如,在上一級目錄 ../test.txt

上述代碼如果運行出現編碼 BUG,注意修改以下 open 函數部分代碼,通過 encoding = "utf-8" 設置文件打開時的編碼。

# 打開文件
f = open(file, encoding="utf-8")

逐行讀取文件內容

通過循環調用文件對象,可以逐行輸出文件內容。

# 文件名
file = "test.txt"
# 打開文件
f = open(file, encoding="utf-8")
# 循環逐行讀取
for line in f:
    print(line)
# 關閉文件
f.close()

輸出的內容如下圖所示。

20201202220619775[1].png

在這里逐行讀取多了一個換行,原因是在 txt 文件中,每行的末尾默認有一個換行,print 函數輸出也會帶一個換行,所以出現 2 個回車符,解決辦法,可以使用 print 函數的第二個參數。

# 文件名
file = "test.txt"
# 打開文件
f = open(file, encoding="utf-8")
# 循環逐行讀取
for line in f:
    print(line,end="")
# 關閉文件
f.close()

逐行讀取方法 readlines

使用 readlines 方法可以將數據一次性讀取到一個列表中,例如下述代碼。

# 文件名
file = "test.txt"
# 打開文件
f = open(file, encoding="utf-8")
# 逐行讀取
data = f.readlines()
# 關閉文件
f.close()

print(data)

輸出內容中,可以看到每行讀取到的字符串都帶一個 \n 換行符。

['夢想橡皮擦\n', '是一個大佬\n', '真的是一個大佬\n', '我自己都信了']

with 上下文

在 Python 中為了防止忘記打開文件之后,在進行關閉,提供了一個 with 關鍵詞解決該問題,語法格式如下:

with open(待打開文件) as 文件對象:
    文件操作代碼塊

有了該語法之后,前文的代碼可以修改為:

file = "test.txt"
# 打開文件
with open(file,encoding="utf-8") as f:
    # 讀取文件全部內容
    read_str = f.read()
    print(read_str)

讀取文件還包含其它的幾個方法,可以自行嘗試。

12.2.2 寫入文件

寫入文件,泛指寫入到本地硬盤上。

在學習寫入文件之前,需要先擴展一下 open 函數,該函數目前已經掌握 2 個參數,第一個是操作的文件,第二個是文件的編碼 encoding,在補充一個文件打開模式 mode 參數,open 函數中該參數的默認值是 r ,代碼寫作 open("text.txt",mode="r",encoding="utf-8") 表示以只讀的方式打開文件,如果想要向文件中寫入內容,需要將 mode 參數設置為 w。關于 mode 參數還有其它值,不要著急,后續會學習到,先記住 2 個即可。

文件寫內容的語法格式為:

文件對象.write(待寫入內容)

具體案例代碼:

# 文件地址,注意提前在當前目錄新建一個 test.txt 文件
file = "test.txt"
# 打開文件
with open(file, mode="w", encoding="utf-8") as f:
    # 寫入文件內容
    f.write("我是即將被寫入的內容")

注意,待寫入的內容需為字符串類型,其它類型寫入會報錯。該種方式寫入內容之后,原內容會被覆蓋,如果想要在文件中追加數據,用到的是 mode = a

寫入多行數據
通過 write 方法可以寫入單行數據,如果想要寫入多行數據,可以在 with 代碼塊中,寫上多個 write 方法即可。注意 write 方法默認在行尾不添加換行符,如果希望加上換行符,需手動添加。

例如下述代碼:

file = "test.txt"
# 打開文件
with open(file, mode="w", encoding="utf-8") as f:
    # 寫入文件內容
    f.write("我是即將被寫入的內容\n")
    f.write("我是即將被寫入的內容")

12.3 shutil 模塊

shutil 模塊可以在 Python 代碼中快速的操作文件,導入該模塊使用 import shutil 即可。

12.3.1 文件復制

使用該模塊中 shutil 對象的 copy 方法可以對文件進行復制操作。

shutil.copy(舊文件,新文件)

書寫成真實代碼如下:

import shutil

shutil.copy("test.txt","aaa.txt")
shutil.copy("test.txt","../aaa.txt") # 不同目錄拷貝

12.3.2 目錄復制

copytree 方法語法格式與 copy 一致,只不過該方法是用來復制目錄的,如果目錄下面有子目錄或文件一起復制。

import shutil
# 第一個參數是舊目錄,第二個參數是新目錄
shutil.copytree("../1","a4")

執行代碼時,需要確定新目錄不存在,如果存在會報錯。

12.3.3 多用的 move 方法

使用 move 方法可以移動文件。

shutil.move(舊文件,新文件)

移動文件一定要確保舊文件存在,移動之后舊文件將移動到新文件位置。

使用 move 方法可以修改文件名,在移動文件的過程中,如果新舊文件名稱不一致,可實現移動文件并重命名的效果。

使用 move 方法還可以移動目錄,移動目錄時會將該目錄下的所有文件一起移動。當然如果新舊目錄名稱不一致,還可以實現移動目錄并重命名的效果。

12.3.4 刪除有數據的目錄

使用 rmtree 可以刪除有數據的目錄,相當于直接清空該目錄下的所有目錄和文件,再順便把該目錄也刪除了。具體內容自行測試即可。

12.4 補充知識

12.4.1 zipFile 模塊

通過該模塊可以直接對文件進行壓縮與解壓操作。后續滾雪球中將補充該部分知識。

12.4.2 認識編碼

在本篇博客中主要涉及編碼的地方就是 open 函數中的 encoding 參數,我們將該參數的值設置為了 utf-8,在很多程序中設置為該值可以解決很多潛在的編碼 BUG。

本部分內容展開講解會占用很大篇幅,這里只說明以下幾點知識。

  1. UTF-8 這幾個字母的寫法你要記住,大小寫都可以;
  2. UTF-8 中有個 BOM 文件頭,這里不細說,如果發現 UTF-8 解決不了編碼問題,那就設置為 utf-8-sig 嘗試解決。

12.5 這篇博客的總結

Python 文件操作其實核心還是對模塊的應用,熟練的使用 Python 給我們內置好的模塊能極大的提高編寫代碼的效率,更好的完成業務上的邏輯。

想學 Python 爬蟲,可以訂閱橡皮擦專欄哦~ ???????? 點擊發現驚喜 ????????

??????????


如果你想跟博主建立親密關系,可以關注同名公眾號 夢想橡皮擦,近距離接觸一個逗趣的互聯網高級網蟲。
博主 ID:夢想橡皮擦,希望大家 點贊、評論、收藏。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容