【问题标题】:How to delete recursively empty folders in Python3?如何在 Python3 中递归删除空文件夹?
【发布时间】:2014-06-22 17:25:20
【问题描述】:

我正在尝试删除目录的空文件夹。

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)

我也尝试过:

import shutil
shutil.rmtree(path)

但这会删除所有内容,即使是那些包含内容的文件夹。问题是我需要从内到外这样做,如果我有:

root_folder
  child_folder1
    grandchild_folder1.1 (empty)
  child_folder2
    granchild_folder2.1
    granchild_folder2.2 (empty)

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

【问题讨论】:

    标签: python python-3.x directory


    【解决方案1】:

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

    【讨论】:

    • 太棒了!但是我忘了说我的功能不起作用,所以我必须更改其他内容。
    • 完成!我不得不更改 remove_empty_dir(os.path.realpath(dirname)) 并改写 remove_empty_dir(os.path.realpath(os.path.join(root, dirname))) 。谢谢!
    • 应该 remove_empty_dir()be os.rmdir() 吗? @falsetru
    • @alper,不,应该是remove_empty_dir。它来自OP的代码。 os.rmdir(..) 将为非空目录引发 OSError
    • 啊,问题本身,不清楚。我还可以检查文件夹的状态为空或不使用:next(os.scandir(path), None) is None 并应用 os.rmdir(),因为os.walk() 构建了目录内容列表@falsetru
    【解决方案2】:

    在 Python 3 中使用 pathlib 库,这是一个单行(除了包含)。在 target_path 下面的 sn -p 是你要清理的树的根的字符串:

    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]
    

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

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

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

    【讨论】:

      【解决方案3】:
      def remove_empty_dirs(dir_path):
          p1 = subprocess.Popen(["find", dir_path, "-type", "d", "-empty", "-print0"], stdout=subprocess.PIPE,)
          p2 = subprocess.Popen(["xargs", "-0", "-r", "rmdir"], stdin=p1.stdout, stdout=subprocess.PIPE)
          p1.stdout.close()
          p2.communicate()
      

      【讨论】:

      • 评论会很好地描述您为什么建议替代解决方案,但我喜欢您不使用“os”库,如 os.rmdir() 或类似的。我之前经历过它会导致僵尸进程,所以我尽量避免这种情况。因此,此解决方案与我相关。
      猜你喜欢
      • 2014-06-21
      • 2015-04-22
      • 1970-01-01
      • 2022-07-16
      • 2012-04-03
      • 1970-01-01
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      相关资源
      最近更新 更多