如何删除Python3中的递归空文件夹?

for*_*vas 3 python directory python-3.x

我想删除目录的空文件夹.

def remove_empty_dir(path):
    try:
        os.rmdir(path)
    except OSError:
        pass

def remove_empty_dirs(path):
    for root, dirnames, filenames in os.walk(path):
        for dirname in dirnames:
            remove_empty_dir(os.path.realpath(os.path.join(root, dirname)))

remove_empty_dirs(path)
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

import shutil
shutil.rmtree(path)
Run Code Online (Sandbox Code Playgroud)

但这会删除所有内容,甚至包含内容的文件夹.问题是我需要从内到外进行,这样如果我有:

root_folder
  child_folder1
    grandchild_folder1.1 (empty)
  child_folder2
    granchild_folder2.1
    granchild_folder2.2 (empty)
Run Code Online (Sandbox Code Playgroud)

该程序应删除grandchild_folder1.1,child_folder1和child_folder2.2,但不删除其余部分.

fal*_*tru 5

os.walk接受可选topdown参数(默认值:True).

通过提供topdown=False,您可以首先从子目录迭代.

def remove_empty_dirs(path):
    for root, dirnames, filenames in os.walk(path, topdown=False):
        for dirname in dirnames:
            remove_empty_dir(os.path.realpath(os.path.join(root, dirname)))
Run Code Online (Sandbox Code Playgroud)


lab*_*oid 5

使用 Python 3 中的 pathlib 库,这是一个单行代码(除了 include 之外)。在下面的代码片段中,target_path 是要清理的树根的字符串:

from pathlib import Path
import os

[os.removedirs(p) for p in Path(target_path).glob('**/*') if p.is_dir() and len(list(p.iterdir())) == 0]
Run Code Online (Sandbox Code Playgroud)

为了使其不那么密集并且更容易理解,这是在没有列表理解的情况下编写的相同内容

for p in Path(target_path).glob('**/*'):
    if p.is_dir() and len(list(p.iterdir())) == 0:
        os.removedirs(p)
Run Code Online (Sandbox Code Playgroud)

这里有趣的功能是 if 语句过滤文件系统树上叶子的空目录。os.removdirs() 删除空叶子上方的所有空文件夹。如果分支上有多个空叶子,删除最后一个空叶子将导致 os.removdirs() 沿着分支向上走。因此,所有空目录都会在循环的单次迭代中消失,无需递归!