在python中递归删除文件夹

我在删除空目录时有问题。这是我的代码:

for dirpath, dirnames, filenames in os.walk(dir_to_search):
//other codes


try:
os.rmdir(dirpath)
except OSError as ex:
print(ex)

参数dir_to_search是我传递需要完成工作的目录的地方。这个目录看起来是这样的:

test/20/...
test/22/...
test/25/...
test/26/...

注意,上面所有的文件夹都是空的。当我运行这个脚本时,文件夹2025单独被删除!但是文件夹2526不会被删除,即使它们是空文件夹。

编辑:

我得到的例外是:

[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/26'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/25'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27/tmp'

我哪里错了?

264311 次浏览

试试shutil.rmtree:

import shutil
shutil.rmtree('/path/to/your/dir/')

os.walk()的默认行为是从根遍历到叶。在os.walk()中设置topdown=False从叶到根。

尝试Python标准库中的shutil中的rmtree()

命令(由Tomek给出)不能删除一个文件,如果它是只读。因此,我们可以使用-

import os, sys
import stat


def del_evenReadonly(action, name, exc):
os.chmod(name, stat.S_IWRITE)
os.remove(name)


if  os.path.exists("test/qt_env"):
shutil.rmtree('test/qt_env',onerror=del_evenReadonly)
最好使用绝对路径,只导入rmtree函数 from shutil import rmtree 因为这是一个大的包,上面的行只会导入所需的函数
from shutil import rmtree
rmtree('directory-absolute-path')

下面是我的纯pathlib递归目录解链接器:

from pathlib import Path


def rmdir(directory):
directory = Path(directory)
for item in directory.iterdir():
if item.is_dir():
rmdir(item)
else:
item.unlink()
directory.rmdir()


rmdir(Path("dir/"))

只是为下一个寻找micropython解决方案的人,这完全基于os (listdir, remove, rmdir)。它既不完整(特别是在错误处理方面)也不花哨,但它在大多数情况下都可以工作。

def deltree(target):
print("deltree", target)
for d in os.listdir(target):
try:
deltree(target + '/' + d)
except OSError:
os.remove(target + '/' + d)


os.rmdir(target)

下面是递归解:

def clear_folder(dir):
if os.path.exists(dir):
for the_file in os.listdir(dir):
file_path = os.path.join(dir, the_file)
try:
if os.path.isfile(file_path):
os.unlink(file_path)
else:
clear_folder(file_path)
os.rmdir(file_path)
except Exception as e:
print(e)

这里是另一个纯pathlib解决方案,但是没有递归:

from pathlib import Path
from typing import Union


def del_empty_dirs(base: Union[Path, str]):
base = Path(base)
for p in sorted(base.glob('**/*'), reverse=True):
if p.is_dir():
p.chmod(0o666)
p.rmdir()
else:
raise RuntimeError(f'{p.parent} is not empty!')
base.rmdir()

对于Linux用户,您可以简单地以python方式运行shell命令

import os
os.system("rm -r /home/user/folder1  /home/user/folder2  ...")

如果遇到任何问题,则使用rm -rf代替rm -r 但是记住f将强制删除目录

其中rm代表删除-r代表递归地-rf代表递归+强制

注意:不管目录是否为空,它们都会被删除。

命令os.removedirs是这项工作的工具,如果你只寻找一个要删除的路径,例如:

os.removedirs("a/b/c/empty1/empty2/empty3")

将删除empty1/empty2/empty3,但保留a/b/c(假设c有一些其他内容)。

    removedirs(name)
removedirs(name)
        

Super-rmdir; remove a leaf directory and all empty intermediate
ones.  Works like rmdir except that, if the leaf directory is
successfully removed, directories corresponding to rightmost path
segments will be pruned away until either the whole path is
consumed or an error occurs.  Errors during this latter phase are
ignored -- they generally mean that a directory was not empty.

这里有一个python式和无递归的解决方案

>>> for e in sorted(p.rglob('**/*'), key=lambda v: v.is_dir()):
...     try:
...         e.unlink()
...     except IsADirectoryError:
...         e.rmdir()

rglob()递归地给出路径p中的所有文件和目录。sorted()及其key参数会确保结果是按文件顺序排列的,最后是目录顺序的。这使得可以先删除所有目录的文件,从而使所有目录为空。

try...except...部分阻止你使用廉价的if语句。