我在删除空目录时遇到问题。这是我的代码:
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/...
请注意,以上所有文件夹都是空的。当我运行此脚本时,仅文件夹 20
、25
就会被删除!但是文件夹 25
和 26
不会被删除,即使它们是空文件夹。
编辑:
我得到的例外是:
[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'
我在哪里犯错?
rmdir /path/to/25th/folder
正在删除整个目录。这意味着该目录是一个空目录!
这是我的纯 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/"))
在 Python 标准库的 shutil
中尝试 rmtree()
rmtree
是否删除了整个目录?我猜它类似于rm -Rf $DIR
最好使用绝对路径并仅导入 rmtree 函数 from shutil import rmtree
,因为这是一个大包,上面的行只会导入所需的函数。
from shutil import rmtree
rmtree('directory-absolute-path')
只是对于下一个搜索 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)
如果文件是只读的,该命令(由 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)
NameError: name 'stat' is not defined
。它是如何定义的?
这是一个递归解决方案:
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)
如果您只是在寻找要删除的单个路径,则命令 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.
这是另一个纯路径库解决方案,但没有递归:
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()
这是一个pythonic和无递归的解决方案
>>> 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
语句。
对于Linux用户,您可以简单地以pythonic方式运行shell命令
import os
os.system("rm -r /home/user/folder1 /home/user/folder2 ...")
如果遇到任何问题,请使用 rm -rf
而不是 rm -r
,但请记住 f 将强制删除目录。
其中 rm
代表 remove,-r
代表 recursively,而 -rf
代表 recursively + forcefully。
注意:目录是否为空都没有关系,它们将被删除。
不定期副业成功案例分享
rmtree
是否删除了整个目录?我猜它类似于rm -Rf $DIR
import os for root, dirs, files in os.walk(top, topdown=False): for name in dirs: os.rmdir(os.path.join(root, name))