简体   繁体   English

递归删除python中的文件夹

[英]Deleting folders in python recursively

I'm having a problem with deleting empty directories.我在删除空目录时遇到问题。 Here is my code:这是我的代码:

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

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

The argument dir_to_search is where I'm passing the directory where the work needs to be done.参数dir_to_search是我传递需要完成工作的目录的位置。 That directory looks like this:该目录如下所示:

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

Note that all the above folders are empty.请注意,以上所有文件夹都是空的。 When I run this script the folders 20 , 25 alone gets deleted!当我运行这个脚本时,文件夹2025单独被删除! But the folders 25 and 26 aren't deleted, even though they are empty folders.但是文件夹2526不会被删除,即使它们是空文件夹。

Edit:编辑:

The exception that I'm getting are:我得到的例外是:

[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'

Where am I making a mistake?我在哪里犯错?

Tryshutil.rmtree :试试shutil.rmtree

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

Here's my pure pathlib recursive directory unlinker:这是我的纯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/"))

The default behavior of os.walk() is to walk from root to leaf. os.walk()的默认行为是从根走到叶。 Set topdown=False in os.walk() to walk from leaf to root.os.walk()中设置topdown=False以从叶子走到根。

从 Python 标准库shutil尝试rmtree()

better to use absolute path and import only the rmtree function from shutil import rmtree as this is a large package the above line will only import the required function.最好使用绝对路径并from shutil import rmtree rmtree 函数,因为这是一个大包,上面的行只会导入所需的函数。

from shutil import rmtree
rmtree('directory-absolute-path')

Just for the next guy searching for a micropython solution, this works purely based on os (listdir, remove, rmdir).只是对于下一个搜索 micropython 解决方案的人来说,这完全基于 os (listdir, remove, rmdir)。 It is neither complete (especially in errorhandling) nor fancy, it will however work in most circumstances.它既不完整(尤其是在错误处理中)也不花哨,但它在大多数情况下都可以工作。

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)

The command (given by Tomek) can't delete a file, if it is read only .该命令(由 Tomek 给出)不能删除文件,如果它是只读的。 therefore, one can use -因此,可以使用 -

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)

Here is a recursive solution:这是一个递归解决方案:

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)

The command os.removedirs is the tool for the job, if you are only looking for a single path to delete, eg:命令os.removedirs是该作业的工具,如果您只是在寻找要删除的单个路径,例如:

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

will remove empty1/empty2/empty3 , but leave a/b/c (presuming that c has some other contents).将删除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.

Here's another pure-pathlib solution , but without recursion:这是另一个纯路径库解决方案,但没有递归:

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

Here is a pythonic and recursion-less solution这是一个pythonic和无递归的解决方案

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

The rglob() gives you all files and directories recursively in the path p . rglob()在路径p中递归地为您提供所有文件和目录。 The sorted() with its key argument takes care that the result is ordered by files first and directories at the end.带有key参数的sorted()确保结果首先按文件排序,最后按目录排序。 This makes it possible to make all directories empty with deleting their files first.这使得可以通过首先删除它们的文件来使所有目录为空。

The try...except... part prevents you from using cheap if statements. try...except...部分会阻止您使用廉价的if语句。

path = "C:\\Personal"
ls = [x[0] for x in os.walk(path)][::-1]
for i in ls:
    if os.path.isdir(i):
        if not os.listdir(i):
            os.rmdir(i)

For Linux users, you can simply run the shell command in a pythonic way对于Linux用户,您可以简单地以pythonic方式运行shell命令

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

If facing any issue then instead of rm -r use rm -rf but remember f will delete the directory forcefully.如果遇到任何问题,请使用rm -rf -r 而不是rm -r但请记住f将强制删除目录。

Where rm stands for remove , -r for recursively and -rf for recursively + forcefully .其中rm代表删除-r代表递归-rf代表递归+强制

Note: It doesn't matter either the directories are empty or not, they'll get deleted.注意:目录是否为空都没有关系,它们将被删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM