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

Amara 790 python file

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

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

ddaa.. 1265

import shutil

shutil.rmtree('/folder_name')

标准库参考:shutil.rmtree.

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

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

  • 请注意,如果有只读文件,`rmtree`将失败:http://stackoverflow.com/questions/2656322/shutil-rmtree-fails-on-windows-with-access-is-denied (68认同)
  • @Malcolm该包是OS函数的包装器.在[POSIX](http://stackoverflow.com/questions/1780599/i-never-really-understood-what-is-posix)系统[rmdir](http://pubs.opengroup.org/onlinepubs/009695399/如果目录不为空,则functions/rmdir.html)将失败.[Ubuntu](http://manpages.ubuntu.com/manpages/lucid/man2/rmdir.2.html)和[Windows](http://technet.microsoft.com/en-us/library/cc726055(v = ws.10).aspx)是这方面POSIX兼容的流行示例. (19认同)
  • 任何人都知道为什么这个功能不在os包中?看起来像os.rmdir是没用的.为什么以这种方式实现它的任何好的论据? (12认同)
  • 这对我不起作用:Traceback(最近一次调用最后一次):文件"foo.py",第31行,在<module> shutil.rmtree(thistestdir)文件中"/usr/lib/python2.6/shutil.py ",第225行,在rmtree onerror中(os.rmdir,path,sys.exc_info())文件"/usr/lib/python2.6/shutil.py",第223行,在rmtree os.rmdir(path)中OSError: [Errno 90]目录不为空:'/ path/to/rmtree' (8认同)
  • 克莱顿:很有可能,当rmtree忙于删除东西时,同时添加了一个文件,"rm -rf"会失败. (4认同)
  • @Malcolm仅在期望删除目录时该目录为空时才有用。您将在对rmdir的调用之前添加要删除的文件的明确列表。例如,确保仅删除程序已创建的文件。打开文件时,我认为它类似于O_EXCL -在受影响的文件上存在先决条件。而且,就像Elder所说的那样,POSIX (2认同)

kkubasik.. 131

Python文档os.walk():

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

  • 代码本身就是pythonic.在实际程序中使用它而不是shutil.rmtree将是unpythonic:这将忽略"一种明显的做法".无论如何,这是语义,删除downmod. (6认同)
  • @ddaa这是思想的食物,即修辞.我知道我在做什么.我只是认为你可能想通过提供shutil.rmtree可能不适合"合适"的理由来重新考虑"明显的做法". (4认同)
  • @ddaa:虽然使用shutil绝对是最简单的方法,但是此解决方案肯定没有任何不妥协之处。我不会赞成这个答案,但是这次我只是想取消你的反对:) (2认同)
  • @ddaa是否要记录每个已删除的文件或目录是非Python的?我不确定该如何使用shutil.rmtree? (2认同)

Siva Mandadi.. 105

import shutil
shutil.rmtree(dest, ignore_errors=True)

  • 如果您有只读文件,则接受的答案将失败. (22认同)
  • 这与接受的答案有何不同? (6认同)
  • 在我的回答中,使用`onerror`参数而不是`ignore_errors`.这样,只读文件将被删除而不是被忽略. (3认同)

yota.. 19

从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实例.不错,但可能不是最快的.


Dave Chandle.. 8

来自docs.python.org:

此示例显示如何在Windows上删除某些文件的只读位设置的目录树.它使用onerror回调清除readonly位并重新尝试删除.任何后续故障都会传播.

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)


小智.. 7

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,则会引发异常.请输入此处的代码


P M.. 5

如果你确定,你想要删除整个目录树,并且对dir的内容不再感兴趣,那么爬行整个目录树就是愚蠢......只需从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])

  • -1.使用`shutil.rmdir`的全部意义是将您与操作系统的类型隔离开来. (32认同)
  • 是的,但使用shutil使代码跨平台并抽象出平台细节. (3认同)
  • 我理解这个概念,但是当一个人完全清楚他想要完全删除文件夹的事实时,那么抓取整个文件树有什么意义呢?shutil.rmdir专门调用os.listdir(),os.path.islink()等等.有些检查实际上并不总是需要,因为所有需要的是取消链接文件系统节点.除了一些构建系统,比如MSWindows for MSAuto/WinCE开发,那么shtuil.rmdir几乎总会失败,因为基于MSAuto批处理的开发会在不成功的退出时锁定一些奇怪的构建文件,只有rmdir/S/Q或者重启才有助于清理他们. (2认同)
  • 是的,只是rm更接近内核,使用更少的时间,内存和CPU .....并且正如我所说,我使用这种方法的原因是因为MSAuto批量构建脚本留下的锁... (2认同)
  • 我不认为这个答案应该低于1,因为它为读者可能感兴趣的某些情况提供了一个非常好的参考.我喜欢按顺序排列多个方法.所以即使我不需要使用它,我现在知道它可以完成以及如何完成. (2认同)

Charles Chow.. 5

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

  • 这引入了可能的比赛条件 (6认同)

JinSnow.. 5

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

  • 请修复缩进并编码`if files [0] ==“ desktop.ini”或: (4认同)

归档时间:

查看次数:

591471 次

最近记录:

12 月 前