Python結(jié)合os模塊和shutil模塊實現(xiàn)本地文件自動化操作
以下是一些os庫和shutil庫中常用的命令,可以實現(xiàn)各種便捷的文件操作,我們可以通過以下命令進(jìn)行模塊的導(dǎo)入:
import os import shutil import stat # 當(dāng)然有的時候我們會想過濾掉隱藏文件,就可以調(diào)用這個包
1. 文件路徑的操作
在進(jìn)行文件操作之前,我們首先需要知道文件路徑如何給,一般我們通過 r 標(biāo)識符來告訴程序這個是一個文件路徑,例如:
folder_path = r"C:\Users\22330\Desktop\進(jìn)行中"
那么接下來我們就可以在這個文件夾中進(jìn)行操作了,如果我們需要組合多個路徑,就可以使用 os 模塊 path 下的 join 功能了,這個的具體作用其實就是加一個 斜杠\ 再連接路徑,這樣你就可以一直往子文件夾進(jìn)了:
folder_path = r"C:\Users\22330\Desktop\進(jìn)行中" file_to_copy = os.path.join(folder_path, "testCopy") print(file_to_copy) # C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy
那如果我們想要回到上一層文件夾,應(yīng)該如何做呢?使用 dirname 即可:
folder_path = r"C:\Users\22330\Desktop\進(jìn)行中" parent_path = os.path.dirname(folder_path) print(parent_path) # C:\Users\22330\Desktop
2. 復(fù)制
2.1 文件的復(fù)制
好,那么我們現(xiàn)在已經(jīng)知道如何操作路徑了,接下來我們看復(fù)制,需要注意的是,os 模塊本身確實沒有直接提供文件復(fù)制的功能,它只是有文件操作的基礎(chǔ),因此要實現(xiàn)文件的復(fù)制,我們可以使用shutil模塊,這個會更加方便:
1、這里分兩種情況,一種是你復(fù)制的時候不保留元信息,比如文件創(chuàng)建時間這些,那么就可以用copy方法:
folder_path = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy" shutil.copy(os.path.join(folder_path, "1.jpg"), os.path.join(folder_path, "1_copy.jpg"))

注意,我是粘貼到了同一個文件夾,這個時候時間是變化了的,代表并沒有保留初始的創(chuàng)建日期。
2、第二種就是你需要保留文件的元信息,我們就可以使用copy2方法:
folder_path = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy" shutil.copy2(os.path.join(folder_path, "1.jpg"), os.path.join(folder_path, "1_copy2.jpg"))

這個時候你可以觀察到,copy2 保留了原始的元信息。
2.2 文件夾的復(fù)制
在程序中,是會非常清楚區(qū)分文件夾和文件的,可以通過 os.path.isdir 或者 os.path.isfile 進(jìn)行區(qū)分:
比如 folder_path 下有一個命名為 1 的文件夾,和一個 1.jpg 的圖片文件,就可以通過isdir 和 isfile 做區(qū)分
folder_path = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy" print(os.path.isdir(os.path.join(folder_path, "1.jpg"))) # False print(os.path.isfile(os.path.join(folder_path, "1.jpg"))) # True print(os.path.isfile(os.path.join(folder_path, "1"))) # False print(os.path.isdir(os.path.join(folder_path, "1"))) # True
在python中,如果需要復(fù)制某個文件夾,只需要使用 shutil 模塊下的 copytree 方法,如下:
folder_path = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy" # 兩個參數(shù),第一個是要復(fù)制的路徑,第二個是存放的路徑,同時可以進(jìn)行文件夾名字的修改 shutil.copytree(os.path.join(folder_path,"1"), os.path.join(folder_path, "1_copy"))

3. 移動(剪切)
如果想要移動某個文件,那么我們完全可以通過 os 模塊下的rename方法實現(xiàn),下面是將1.jpg這張圖片移動到上一級目錄中
folder_path = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy" os.rename(os.path.join(folder_path,"1.jpg"), os.path.join(os.path.dirname(folder_path), "1.jpg"))
那如果是想要移動文件夾呢? 我們可以使用shutil.move 方法
sourse_folder = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy\1" destination_folder = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)new_location" # 注意這種寫法只是將 1 文件夾下所有文件移動到 new_location 下,并不會再在 new_location 下新建一個文件夾為 1 # 如果要保留1文件夾本身,那么就是寫作 destination_folder = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)new_location\1" shutil.move(sourse_folder, destination_folder) # destination_folder如果不存在,會自動新建
或者同樣地,我們也可以使用os.rename 方法
os.rename(sourse_folder, destination_folder) # destination_folder如果不存在,會自動新建
4. 刪除
在python中,如果需要刪除文件夾,我們可以用os 模塊下的rmdir方法:
del_folder = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy\1_copy" os.rmdir(del_folder)
但是這個方法有一個限制,就是要刪除的文件夾一定要是空文件夾,如果是非空文件夾,就會報錯:

所以我們有一個更加徹底的方式,就是使用shutil的rmtree方法:
del_folder = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy\1_copy" shutil.rmtree(del_folder)
那如果我們需要刪除的是文件,就可以使用os 的 remove 方法或者unlink方法:
del_file = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy\1_copy.jpg" os.remove(del_file) os.unlink(del_file) # unlink和remove 的功能一樣
5. 新建
如果是想要新建一個文件夾,那可以采用os 模塊下的mkdir或者makedirs方法,只不過后者多了一個exist_ok的參數(shù),用來指定如果文件夾已經(jīng)存在,是否會報錯,比如我們文件夾已存在的時候,如果使用mkdir:
mk_folder = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy\testFolder" os.mkdir(mk_folder)
就會報這樣的錯誤:“[WinError 183] 當(dāng)文件已存在時,無法創(chuàng)建該文件”

但是如果我們使用 makedirs,并給上 exist_ok = True,這個問題就成功解決了:
mk_folder = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy\testFolder" os.makedirs(mk_folder, exist_ok=True) # 不刪除文件夾中原有的文件,且不報錯
新建文件的話,就有很多不同的情況了,例如txt,xlsx,jpg,pptx等,這里我們以創(chuàng)建一個最簡單的txt文檔為例:
mk_folder = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)testCopy\testFolder"
txt_to_make = os.path.join(mk_folder, "test.txt")
with open(txt_to_make, "w") as f: # w 代表的是寫入狀態(tài)
f.write("這是一個測試文件")
f.close() # 關(guān)閉文件

6. 關(guān)于隱藏文件的處理方式
這里就涉及我們上面提到的一個非常重要的包,叫做stat,我們先看一下目錄下的隱藏文件:
如果我們文件系統(tǒng)中沒有顯示隱藏文件,默認(rèn)是看不見的,但是程序能夠找出來
于是我們通過下面的程序打印出所有的文件,listdir 在這里是羅列所有的文件,返回一個列表,我們遍歷即可:
folder_dir = r"C:\Users\22330\Desktop\進(jìn)行中"
for item in os.listdir(folder_dir):
print(item)

可以發(fā)現(xiàn),隱藏文件都以~開頭,其實有的時候也以 . 開頭,如果我們簡單寫作下面的程序:
folder_dir = r"C:\Users\22330\Desktop\進(jìn)行中"
for file in os.listdir(folder_dir):
# 如果是隱藏文件,不顯示
if not file.startswith(".") and not file.startswith("~"):
print(file)
看上去確實沒問題,但是容易誤傷友軍,比如有的文件就是以~開頭的:

所以僅僅通過開始字符做判斷,是不合理的,因此就引入了我們的stat:
folder_dir = r"C:\Users\22330\Desktop\進(jìn)行中"
for file in os.listdir(folder_dir):
file_name = os.path.join(folder_dir,file)
file_stat = os.stat(file_name) # 獲取文件屬性
is_hidden = file_stat.st_file_attributes & stat.FILE_ATTRIBUTE_HIDDEN # 按位與 獲取隱藏狀態(tài)
print(is_hidden) # 測試用,為2代表是隱藏文件,為0代表不是隱藏文件
if not is_hidden:
print(file)

7. 三個小案例
7.1 文件分類
你有一個文件夾 data(可以自己新建一個做測試),里面亂七八糟地放著 .txt 文本文件和 .xlsx 文件,需要將文件分類
import os
import shutil
folder_dir = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)data" # 文件夾路徑
file_type = []
# 統(tǒng)計文件類型
for item in os.listdir(folder_dir):
# 通過splitext獲取文件擴(kuò)展名,并去掉點號
file_type.append(os.path.splitext(item)[1].replace(".",""))
# 為不同文件類型創(chuàng)建文件夾
for tp in list(set(file_type)): # 通過set去重
os.makedirs(os.path.join(folder_dir, tp), exist_ok=True)
# 移動文件到對應(yīng)的文件夾
for item in os.listdir(folder_dir):
if os.path.isfile(os.path.join(folder_dir, item)): # 如果是文件類型才進(jìn)行移動
tp = os.path.splitext(item)[1].replace(".","") # 獲取文件類型
shutil.move(os.path.join(folder_dir, item), os.path.join(folder_dir, tp, item))
print(f"已移動: {item}")
7.2 清理空文件夾
場景描述:有時候下載軟件會產(chǎn)生很多空的臨時文件夾,這個時候手動刪除太麻煩,寫個程序自動化處理
任務(wù)要求:
- 遍歷某個指定目錄(只遍歷第一層即可)
- 判斷每一個條目是否是文件夾(不是文件)
- 如果是文件夾,并且這個文件夾是空的(里面沒有任何文件或子文件夾),就把它刪除
import os
folder_dir = r"C:\Users\22330\Desktop\進(jìn)行中\(zhòng)測試文件夾" # 文件夾路徑
for item in os.listdir(folder_dir):
if os.path.isdir(os.path.join(folder_dir, item)): # 如果是文件類型才進(jìn)行判斷
if len(os.listdir(os.path.join(folder_dir, item))) == 0: # 根據(jù)枚舉的長度判斷是否為空文件夾
os.rmdir(os.path.join(folder_dir, item)) # 如果是,則刪除
print(f"已刪除空文件夾: {item}")
7.3 文件備份
場景描述:這是一個結(jié)合了 “隱藏文件過濾” 和 “復(fù)制” 的綜合問題。
任務(wù)要求:
- 定義一個源目錄
source和一個備份目錄backup - 將
source里的所有文件復(fù)制到backup
關(guān)鍵難點:
- 不要復(fù)制隱藏文件(使用剛才學(xué)的
stat屬性判斷) - 不要復(fù)制文件夾(只復(fù)制文件)
- 復(fù)制時要保留文件的修改時間(元數(shù)據(jù))
import os
import stat
import shutil
folder_dir = r"C:\Users\22330\Desktop\進(jìn)行中" # 初始文件夾路徑
backup_dir = os.path.join(folder_dir, "backup") # 備份文件夾路徑
os.makedirs(backup_dir, exist_ok=True) # 備份文件夾
for item in os.listdir(folder_dir):
if os.path.isfile(os.path.join(folder_dir, item)): # 排除文件夾類型
file_stat = os.stat(os.path.join(folder_dir, item)) # 判斷是否是隱藏文件
is_hidden = file_stat.st_file_attributes & stat.FILE_ATTRIBUTE_HIDDEN
if not is_hidden: # 如果不是隱藏文件,保留元數(shù)據(jù)復(fù)制
shutil.copy2(os.path.join(folder_dir, item), os.path.join(backup_dir, item))
print(f"已備份: {item}")
掌握代碼操作文件系統(tǒng),是實現(xiàn)自動化的第一步,希望通過上面的講解,你至少可以實現(xiàn)基本的文件系統(tǒng)操作
到此這篇關(guān)于Python結(jié)合os模塊和shutil模塊實現(xiàn)本地文件自動化操作的文章就介紹到這了,更多相關(guān)Pytho文件自動化操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Python如何利用pymysql封裝項目通用的連接和查詢
一個項目通常都需要有數(shù)據(jù)庫,本文就來為大家詳細(xì)講講Python如何利用pymysql簡單分裝一個通用的連接,關(guān)閉和查詢,需要的可以參考一下2022-07-07
Pycharm使用matplotlib警告\不能顯示的問題及解決
在PyCharm中使用matplotlib畫圖時遇到警告和圖像顯示問題,通過在代碼中添加`mpl.use('TkAgg')`或`plt.switch_backend('TkAgg')`,可以解決警告并彈出顯示完整的圖像窗口,同時,文章還列舉了matplotlib的其他backend選項,如Qt4Agg、Qt5Agg、WXAgg等2025-02-02
Django框架獲取form表單數(shù)據(jù)方式總結(jié)
這篇文章主要介紹了Django框架獲取form表單數(shù)據(jù)方式總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04
python爬蟲實現(xiàn)教程轉(zhuǎn)換成 PDF 電子書
本文給大家分享的是使用python爬蟲實現(xiàn)把《廖雪峰的 Python 教程》轉(zhuǎn)換成PDF的方法和代碼,有需要的小伙伴可以參考下2017-02-02

