问题:递归删除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单独被删除!但是,文件夹25,并26不会被删除,即使它们是空文件夹。

编辑:

我得到的exceptions是:

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

我在哪里弄错了?

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. 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! But the folders 25 and 26 aren’t deleted, even though they are empty folders.

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?


回答 0

尝试shutil.rmtree

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

Try shutil.rmtree:

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

回答 1

的默认行为os.walk()是从根走到叶。设置topdown=Falseos.walk()从叶片到步行到根。

The default behavior of os.walk() is to walk from root to leaf. Set topdown=False in os.walk() to walk from leaf to root.


回答 2

这是我的纯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/"))

Here’s my pure pathlib recursive directory unlinker:

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

回答 3

尝试rmtree()shutilPython标准库

Try rmtree() in shutil from the Python standard library


回答 4

最好使用绝对路径并仅导入rmtree函数, from shutil import rmtree 因为这是一个大包,上面的行将仅导入所需的函数。

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

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('directory-absolute-path')

回答 5

仅针对下一个正在寻找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)

Just for the next guy searching for a micropython solution, this works purely based on 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)

回答 6

如果该命令 是只读的,则该命令(由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)

The command (given by Tomek) can’t delete a file, if it is read only. 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)

回答 7

这是另一个纯路径库解决方案,但没有递归:

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

回答 8

这是一个递归解决方案:

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)

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)

回答 9

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

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

其中,rm代表删除,并-r递归

For Linux users, you can simply run the shell command in a pythonic way

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

where rm stands for remove and -r for recursively


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。