如何删除 / 删除不为空的文件夹?

尝试删除不为空的文件夹时,出现 “访问被拒绝” 错误。我尝试使用以下命令: os.remove("/folder_name")

删除 / 删除不为空的文件夹 / 目录的最有效方法是什么?

答案

import shutil

shutil.rmtree('/folder_name')

标准库参考:shutil.rmtree

按照设计, rmtree在包含只读文件的文件夹树上将失败。如果要删除该文件夹而不管它是否包含只读文件,请使用

shutil.rmtree('/folder_name', ignore_errors=True)

来自os.walk()的 python 文档

# Delete everything reachable from the directory named in 'top',
# assuming there are no symbolic links.
# CAUTION:  This is dangerous!  For example, if top == '/', it
# could delete all your disk files.
import os
for root, dirs, files in os.walk(top, topdown=False):
    for name in files:
        os.remove(os.path.join(root, name))
    for name in dirs:
        os.rmdir(os.path.join(root, name))
import shutil
shutil.rmtree(dest, ignore_errors=True)

从 python 3.4 您可以使用:

import pathlib

def delete_folder(pth) :
    for sub in pth.iterdir() :
        if sub.is_dir() :
            delete_folder(sub)
        else :
            sub.unlink()
    pth.rmdir() # if you just want to delete dir content, remove this line

其中pthpathlib.Path实例。不错,但可能不是最快的。

来自docs.python.org

本示例说明如何在 Windows 上删除目录树,其中某些文件的只读位已设置。它使用 onerror 回调清除只读位并重新尝试删除。任何后续故障都将传播。

import os, stat
import shutil

def remove_readonly(func, path, _):
    "Clear the readonly bit and reattempt the removal"
    os.chmod(path, stat.S_IWRITE)
    func(path)

shutil.rmtree(directory, onerror=remove_readonly)
import os
import stat
import shutil

def errorRemoveReadonly(func, path, exc):
    excvalue = exc[1]
    if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
        # change the file to be readable,writable,executable: 0777
        os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)  
        # retry
        func(path)
    else:
        # raiseenter code here

shutil.rmtree(path, ignore_errors=False, onerror=errorRemoveReadonly)

如果设置了 ignore_errors,错误将被忽略;否则,如果设置了 onerror,则调用该函数以使用参数(func,path,exc_info)处理错误,其中 func 为 os.listdir,os.remove 或 os.rmdir; path 是导致该函数失败的参数。而 exc_info 是 sys.exc_info()返回的元组。如果 ignore_errors 为 false 并且 onerror 为 None,则会引发异常。在此处输入代码

根据 kkubasik 的回答,删除之前检查文件夹是否存在,更可靠

import shutil
def remove_folder(path):
    # check if folder exists
    if os.path.exists(path):
         # remove if exists
         shutil.rmtree(path)
    else:
         # throw your exception to handle this special scenario
         raise XXError("your exception") 
remove_folder("/folder_name")

如果您确定要删除整个目录树,并且不再对目录内容感兴趣,那么爬网整个目录树是愚蠢的…… 只需从 python 调用本机 OS 命令即可。它将更快,更有效且内存消耗更少。

RMDIR c:\blah /s /q

或 * nix

rm -rf /home/whatever

在 python 中,代码看起来像..

import sys
import os

mswindows = (sys.platform == "win32")

def getstatusoutput(cmd):
    """Return (status, output) of executing cmd in a shell."""
    if not mswindows:
        return commands.getstatusoutput(cmd)
    pipe = os.popen(cmd + ' 2>&1', 'r')
    text = pipe.read()
    sts = pipe.close()
    if sts is None: sts = 0
    if text[-1:] == '\n': text = text[:-1]
    return sts, text


def deleteDir(path):
    """deletes the path entirely"""
    if mswindows: 
        cmd = "RMDIR "+ path +" /s /q"
    else:
        cmd = "rm -rf "+path
    result = getstatusoutput(cmd)
    if(result[0]!=0):
        raise RuntimeError(result[1])

只需一些 python 3.5 选项即可完成上述答案。 (我很想在这里找到他们)。

import os
import shutil
from send2trash import send2trash # (shutil delete permanently)

删除文件夹(如果为空)

root = r"C:\Users\Me\Desktop\test"   
for dir, subdirs, files in os.walk(root):   
    if subdirs == [] and files == []:
           send2trash(dir)
           print(dir, ": folder removed")

如果包含此文件的文件夹也删除

elif subdirs == [] and len(files) == 1: # if contains no sub folder and only 1 file 
        if files[0]== "desktop.ini" or:  
            send2trash(dir)
            print(dir, ": folder removed")
        else:
            print(dir)

如果仅包含. srt 或. txt 文件,则删除文件夹

elif subdirs == []: #if dir doesn’t contains subdirectory
        ext = (".srt", ".txt")
        contains_other_ext=0
        for file in files:
            if not file.endswith(ext):  
                contains_other_ext=True
        if contains_other_ext== 0:
                send2trash(dir)
                print(dir, ": dir deleted")

删除小于 400kb 的文件夹:

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total


for dir, subdirs, files in os.walk(root):   
    If get_tree_size(dir) < 400000:  # ≈ 400kb
        send2trash(dir)
    print(dir, "dir deleted")

如果您不想使用shutil模块,则可以使用os模块。

from os import listdir, rmdir, remove
for i in listdir(directoryToRemove):
    os.remove(os.path.join(directoryToRemove, i))
rmdir(directoryToRemove) # Now the directory is empty of files