当我尝试删除一个非空文件夹时,出现了“拒绝访问”的错误。在我的尝试中,我使用了以下命令:os.remove("/folder_name")
。
如何最有效地删除一个非空的文件夹/目录?
import shutil
shutil.rmtree('/folder_name')
rmtree
由设计上不适用于包含只读文件的文件夹树。如果您想删除该文件夹而不管它是否包含只读文件,请使用以下方法:
shutil.rmtree('/folder_name', ignore_errors=True)
rmtree
将失败:https://dev59.com/wnE85IYBdhLWcg3wr1qx。 - Sridhar Ratnakumar来自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))
import shutil
shutil.rmtree(dest, ignore_errors=True)
ignore_errors=True
可以解决这个问题。 - Aventinusonerror
参数而不是 ignore_errors
。这样只读文件将被删除而不是被忽略。 - Dave Chandler从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.Path
实例。不错,但可能不是最快的。
This example shows how to remove a directory tree on Windows where some of the files have their read-only bit set. It uses the onerror callback to clear the readonly bit and reattempt the remove. Any subsequent failure will propagate.
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)
根据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")
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为假且onerror为None,则会引发异常。
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
一样。因此,目录将排在文件之前。如果我们反转排序,那么文件将排在它们各自的容器之前,所以我们可以通过一个遍历单次 unlink/rmdir 它们。pathlib
所承诺的是如此;没有操作声明无法在 Windows 上运行)sorted
内置首先生成由glob
生成器返回的项目列表,然后生成一个新列表,其中包含排序的项目。根据文件数量的不同,这可能导致显着的内存消耗。哦,还有你引入了一个时间复杂度为n log n
的排序。 - danzelos.system
或 subprocess.run
运行 shell 命令更慢。此外,维护一个列表和一个已排序的列表所需的内存可能比启动并运行子进程所需的内存更小。你的情况可能有所不同。 - pepoluanRMDIR c:\blah /s /q
rm -rf /home/whatever
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])
shutil.rmdir
的整个目的就是让你与操作系统的类型隔离开来。 - mtrw这里列出一些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" or:
。 提示:修改后的代码应该还有语法错误。 - Mr_and_Mrs_D
rm -rf
行为,请参见:https://dev59.com/IHRA5IYBdhLWcg3wzhfZ - Ciro Santilli OurBigBook.com