当我试图删除一个非空文件夹时,我得到一个“访问被拒绝”错误。我在尝试中使用了以下命令:os.remove("/folder_name")。

删除一个非空文件夹/目录最有效的方法是什么?


当前回答

只需一些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")

删除包含此文件的also文件夹

    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")

其他回答

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,操作系统。Remove, or os.rmdir;Path是导致该函数失败的参数;exc_info是由sys.exc_info()返回的元组。如果ignore_errors为false且onerror为None,则会引发异常。在这里输入代码

基于递归的纯pathlib解决方案:

from pathlib import Path

def remove_path(path: Path):
    if path.is_file() or path.is_symlink():
        path.unlink()
        return
    for p in path.iterdir():
        remove_path(p)
    path.rmdir()

支持Windows和符号链接

在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 the dir content but not the dir itself, remove this line

其中PTH是一个pathlib。路径实例。不错,但可能不是最快的。

我想添加一个“纯pathlib”方法:

from pathlib import Path
from typing import Union

def del_dir(target: Union[Path, str], only_if_empty: bool = False):
    """
    Delete a given directory and its subdirectories.

    :param target: The directory to delete
    :param only_if_empty: Raise RuntimeError if any file is found in the tree
    """
    target = Path(target).expanduser()
    assert target.is_dir()
    for p in sorted(target.glob('**/*'), reverse=True):
        if not p.exists():
            continue
        p.chmod(0o666)
        if p.is_dir():
            p.rmdir()
        else:
            if only_if_empty:
                raise RuntimeError(f'{p.parent} is not empty!')
            p.unlink()
    target.rmdir()

这依赖于Path是可排序的,长路径总是排在短路径之后,就像str一样。因此,目录将排在文件之前。如果我们反转排序,那么文件就会出现在它们各自的容器之前,所以我们可以简单地一次将它们逐个解除/rmdir链接。

好处:

它不依赖于外部二进制文件:所有东西都使用Python的电池包含的模块(Python >= 3.6) 这意味着它不需要重复启动一个新的子进程来解除链接 它非常快速和简单;你不必实现你自己的递归 它是跨平台的(至少,这是pathlib在Python 3.6中所承诺的;上述操作不能在Windows上运行) 如果需要,可以进行非常细粒度的日志记录,例如,记录每一次删除。

删除一个文件夹,即使它可能不存在(避免Charles Chow回答中的竞态条件),但当其他事情出错时仍然有错误(例如权限问题,磁盘读取错误,文件不是目录)

对于Python 3.x:

import shutil

def ignore_absent_file(func, path, exc_inf):
    except_instance = exc_inf[1]
    if isinstance(except_instance, FileNotFoundError):
        return
    raise except_instance

shutil.rmtree(dir_to_delete, onerror=ignore_absent_file)

Python 2.7的代码几乎是一样的:

import shutil
import errno

def ignore_absent_file(func, path, exc_inf):
    except_instance = exc_inf[1]
    if isinstance(except_instance, OSError) and \
        except_instance.errno == errno.ENOENT:
        return
    raise except_instance

shutil.rmtree(dir_to_delete, onerror=ignore_absent_file)