成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Shutil 標(biāo)準(zhǔn)庫: Python 文件操作的萬用刀

開發(fā) 后端
今天來聊一個(gè)被低估的 Python 標(biāo)準(zhǔn)庫 - shutil 。工作中我們用 Python (尤其是寫一些短小輕快的腳本)雖然經(jīng)常和文件打交道,卻很少用到 shutil 。但實(shí)際上, shutil 提供了比 os 模塊更高級(jí)的文件操作接口,能讓我們寫出更 Pythonic 的代碼。

今天來聊一個(gè)被低估的 Python 標(biāo)準(zhǔn)庫 - shutil 。工作中我們用 Python (尤其是寫一些短小輕快的腳本)雖然經(jīng)常和文件打交道,卻很少用到 shutil 。但實(shí)際上, shutil 提供了比 os 模塊更高級(jí)的文件操作接口,能讓我們寫出更 Pythonic 的代碼。

從一個(gè)真實(shí)場景說起

最近在整理項(xiàng)目代碼時(shí),需要將散落在各處的配置文件歸類到統(tǒng)一目錄。按以往的習(xí)慣,我會(huì)這樣寫:

import os

# 創(chuàng)建目標(biāo)目錄
if not os.path.exists("configs"):
    os.makedirs("configs")

# 移動(dòng)文件
for root, dirs, files in os.walk("."):
    for file in files:
        if file.endswith(".conf"):
            src = os.path.join(root, file)
            dst = os.path.join("configs", file)
            os.rename(src, dst)

這段代碼能完成任務(wù),但存在幾個(gè)問題:

  • 如果目標(biāo)路徑已存在同名文件會(huì)報(bào)錯(cuò)
  • 不支持跨設(shè)備移動(dòng)
  • 沒有保留文件的元數(shù)據(jù)(權(quán)限、時(shí)間戳等)

用 shutil 可以優(yōu)雅地解決這些問題:

import shutil
import os

os.makedirs("configs", exist_ok=True)
for root, dirs, files in os.walk("."):
    for file in files:
        if file.endswith(".conf"):
            src = os.path.join(root, file)
            dst = os.path.join("configs", file)
            shutil.move(src, dst)

看起來差別不大,但 shutil.move() 會(huì):

當(dāng)目標(biāo)路徑已存在同名文件時(shí), shutil.move() 的行為取決于操作系統(tǒng)

  • Windows:如果目標(biāo)文件存在且正在使用,會(huì)拋出 PermissionError ;否則會(huì)靜默覆蓋目標(biāo)文件
  • Unix/Linux:會(huì)遵循操作系統(tǒng)的規(guī)則。如果用戶有權(quán)限,會(huì)覆蓋目標(biāo)文件;否則拋出 PermissionError

支持跨設(shè)備移動(dòng)

"跨設(shè)備"指的是在不同的文件系統(tǒng)或存儲(chǔ)設(shè)備之間移動(dòng)文件,比如從 C 盤移動(dòng)到 D 盤、從本地磁盤移動(dòng)到網(wǎng)絡(luò)驅(qū)動(dòng)器、從固態(tài)硬盤移動(dòng)到 U 盤。

shutil.move() 會(huì)首先嘗試使用 os.rename() ,如果失敗且錯(cuò)誤是跨設(shè)備錯(cuò)誤 errno.EXDEV ,則復(fù)制文件到目標(biāo)位置,驗(yàn)證復(fù)制成功,最后刪除源文件。

保留源文件的所有元數(shù)據(jù)。

shutil 常用操作詳解

1. 復(fù)制文件和目錄

# 復(fù)制文件
shutil.copy("source.txt", "dest.txt")      # 復(fù)制文件內(nèi)容
shutil.copy2("source.txt", "dest.txt")     # 復(fù)制文件內(nèi)容和元數(shù)據(jù)

# 復(fù)制目錄
shutil.copytree("src_dir", "dst_dir")      # 遞歸復(fù)制整個(gè)目錄樹

copy2() 比 copy() 多了preserving metadata 的功能,在需要保留文件屬性時(shí)很有用。

2. 刪除目錄

# 刪除目錄樹
shutil.rmtree("dir_to_remove")             # 遞歸刪除目錄及其內(nèi)容

比 os.rmdir() 強(qiáng)大,后者只能刪除空目錄。

3. 磁盤使用統(tǒng)計(jì)

total, used, free = shutil.disk_usage(".")
print(f"總空間: {total // (2**30)} GiB")
print(f"已使用: {used // (2**30)} GiB")
print(f"可用: {free // (2**30)} GiB")

直觀地獲取磁盤使用情況,免去了手動(dòng)計(jì)算的麻煩。

4. 文件打包與壓縮

# 創(chuàng)建壓縮包
shutil.make_archive("backup", "zip", "source_dir")   # 支持zip、tar等格式

# 解壓縮
shutil.unpack_archive("backup.zip", "extract_dir")

實(shí)用腳本示例

1. 項(xiàng)目備份工具

import shutil
from datetime import datetime
import os

def backup_project(project_path, backup_dir="backups"):
    # 創(chuàng)建以時(shí)間戳命名的備份文件
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    backup_name = f"backup_{timestamp}"
    
    # 確保備份目錄存在
    os.makedirs(backup_dir, exist_ok=True)
    
    # 創(chuàng)建壓縮包
    archive_path = shutil.make_archive(
        os.path.join(backup_dir, backup_name),
        "zip",
        project_path
    )
    
    print(f"備份完成: {archive_path}")

2. 大文件搬運(yùn)工具

import shutil
import os
from pathlib import Path

def move_large_files(src_dir, dst_dir, min_size_mb=100):
    """移動(dòng)大于指定大小的文件到目標(biāo)目錄"""
    dst_path = Path(dst_dir)
    dst_path.mkdir(exist_ok=True)
    
    for root, _, files in os.walk(src_dir):
        for file in files:
            file_path = Path(root) / file
            if file_path.stat().st_size > min_size_mb * 1024 * 1024:
                try:
                    shutil.move(str(file_path), dst_path / file)
                    print(f"已移動(dòng): {file}")
                except Exception as e:
                    print(f"移動(dòng)失敗 {file}: {e}")

3. 智能文件分類器

import shutil
from pathlib import Path
import mimetypes

def organize_files(directory):
    """根據(jù)文件類型自動(dòng)分類文件"""
    directory = Path(directory)
    
    # 遍歷所有文件
    for file_path in directory.rglob("*"):
        if file_path.is_file():
            # 獲取文件類型
            mime_type, _ = mimetypes.guess_type(str(file_path))
            if mime_type:
                category = mime_type.split("/")[0]
                
                # 創(chuàng)建分類目錄
                dest_dir = directory / category
                dest_dir.mkdir(exist_ok=True)
                
                # 移動(dòng)文件
                try:
                    shutil.move(str(file_path), str(dest_dir / file_path.name))
                except Exception as e:
                    print(f"處理{file_path}時(shí)出錯(cuò): {e}")

性能提示

對(duì)于大文件操作,shutil 提供了 copyfileobj() 方法,支持設(shè)置緩沖區(qū)大小:

with open("source.dat", "rb") as fsrc:
    with open("dest.dat", "wb") as fdst:
        shutil.copyfileobj(fsrc, fdst, length=1024*1024)  # 1MB buffer

copytree() 支持多進(jìn)程并行復(fù)制:

from multiprocessing import Pool

def copy_with_progress(src, dst):
    shutil.copy2(src, dst)
    return dst

with Pool(processes=4) as pool:
    shutil.copytree("src_dir", "dst_dir", copy_function=pool.map)

文件屬性操作

1. 權(quán)限和所有權(quán)

import shutil
import os

def mirror_permissions(src, dst):
    # 復(fù)制權(quán)限位
    shutil.copymode(src, dst)
    
    # 復(fù)制所有權(quán)(需要root權(quán)限)
    try:
        shutil.chown(dst, 
                     user=os.stat(src).st_uid,
                     group=os.stat(src).st_gid)
    except PermissionError:
        print("需要管理員權(quán)限來修改所有權(quán)")

2. 元數(shù)據(jù)復(fù)制

import shutil
import os
from datetime import datetime

def show_metadata(path):
    stat = os.stat(path)
    print(f"訪問時(shí)間: {datetime.fromtimestamp(stat.st_atime)}")
    print(f"修改時(shí)間: {datetime.fromtimestamp(stat.st_mtime)}")
    print(f"創(chuàng)建時(shí)間: {datetime.fromtimestamp(stat.st_ctime)}")
    print(f"權(quán)限: {oct(stat.st_mode)[-3:]}")
    print(f"大小: {stat.st_size} bytes")

# 復(fù)制文件并保留所有元數(shù)據(jù)
src = "source.txt"
dst = "dest.txt"
shutil.copy2(src, dst)

print("源文件元數(shù)據(jù):")
show_metadata(src)
print("\n目標(biāo)文件元數(shù)據(jù):")
show_metadata(dst)

總結(jié)

shutil 是一個(gè)設(shè)計(jì)優(yōu)雅的文件操作庫:

  • 提供了比 os 模塊更高級(jí)的接口
  • 自動(dòng)處理各種邊界情況
  • 保持了 Python "batteries included" 的理念

下次遇到文件操作需求,不妨先看看 shutil 是否已經(jīng)提供了合適的工具。畢竟,"不要重復(fù)發(fā)明輪子"也是 Python 的哲學(xué)之一。

責(zé)任編輯:姜華 來源: Piper蛋窩
相關(guān)推薦

2021-04-15 07:53:15

ParkMobile數(shù)據(jù)泄露網(wǎng)絡(luò)犯罪

2019-05-17 10:10:30

優(yōu)衣庫黑客數(shù)據(jù)泄漏

2011-01-20 17:34:01

IPv6雅虎

2010-02-21 18:33:28

文件夾病毒照片影像U盤病毒

2023-05-30 20:19:20

2022-09-05 11:25:22

惡意瀏覽器Chrome惡意擴(kuò)展

2011-12-26 15:31:33

2011-12-22 10:58:37

2009-02-01 21:11:13

Facebook存儲(chǔ)數(shù)據(jù)中心

2015-02-09 10:14:33

2021-04-02 11:09:35

MobiKwik 移動(dòng)支付數(shù)據(jù)泄露

2010-05-04 22:32:37

手機(jī)木馬網(wǎng)絡(luò)安全360手機(jī)衛(wèi)士

2020-07-29 15:09:56

Dave數(shù)據(jù)泄露數(shù)據(jù)庫泄露

2023-01-31 17:07:06

2023-06-13 15:55:54

2013-12-12 17:03:57

Lua腳本語言

2012-08-01 10:45:40

Outlook

2022-09-01 11:21:06

擴(kuò)展惡意代碼

2012-07-04 09:28:41

我查查推廣運(yùn)營Mary

2024-01-09 07:42:46

Shutil 模塊Python 編程工具
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日本精品一区二区三区在线观看视频 | 色在线免费视频 | 欧美三级电影在线播放 | 久热中文字幕 | 久久久久国 | 国产精品精品视频一区二区三区 | 国产精品久久精品 | 日本黄色短片 | 久久精品综合网 | 91亚洲精品久久久电影 | 九九国产在线观看 | 九九亚洲 | 欧美国产日韩一区 | 成年人视频免费在线观看 | 国产精品乱码一二三区的特点 | 天天天堂 | 超碰在线免费 | 在线免费观看黄a | 请别相信他免费喜剧电影在线观看 | 青青草亚洲 | 欧美精品一区二区三区在线 | 自拍视频在线观看 | 久久成人国产精品 | 天天爽夜夜操 | 欧美日韩国产精品一区 | 欧美片网站免费 | 3p视频在线观看 | 中文字幕亚洲一区 | 蜜桃精品视频在线 | 涩涩视频在线观看 | 欧美不卡 | jav成人av免费播放 | 亚洲高清视频一区 | 超碰免费在线 | 午夜av一区二区 | 午夜久久久久久久久久一区二区 | 中文字幕的av | 国产高清免费 | 综合色久| 五月天国产 | 一级毛片观看 |