如何在Python中删除文件夹的内容?

Unk*_*ech 410 python file

如何在Python中删除本地文件夹的内容?

目前的项目适用于Windows,但我也希望看到*nix.

Nic*_*tes 389

更新为仅删除文件并使用注释中建议的os.path.join()方法.如果您还想删除子目录,请取消注释elif语句.

import os, shutil
folder = '/path/to/folder'
for filename in os.listdir(folder):
    file_path = os.path.join(folder, filename)
    try:
        if os.path.isfile(file_path) or os.path.islink(file_path):
            os.unlink(file_path)
        elif os.path.isdir(file_path):
            shutil.rmtree(file_path)
    except Exception as e:
        print('Failed to delete %s. Reason: %s' % (file_path, e))
Run Code Online (Sandbox Code Playgroud)

  • 我收到一个 pylint 警告,其中包含“ except Exception as e:”,内容为“W0703:捕获太一般的异常异常”。是否有更具体的异常需要捕获或者我应该忽略它? (5认同)
  • @JohnHany,我相信你想要捕获OSError. (4认同)
  • 如果您正在使用一个非常大的目录,特别是Windows上的网络目录,并且您可以控制运行该程序的环境,那么使用Py3.5的"os.scandir(文件夹)"函数代替listdir同时.之后语法完全不同,但实现起来非常简单; 如果有人想要的话,很乐意发布. (3认同)

Oli*_*Oli 216

试试shutil模块

import shutil
shutil.rmtree('/path/to/folder')
Run Code Online (Sandbox Code Playgroud)

描述: shutil.rmtree

Docstring:递归删除目录树.

如果shutil.rmtree(path, ignore_errors=False, onerror=None)设置,则忽略错误; 否则,如果shutil.rmtree设置,它被称为处理与参数的误差shutil.rmtree(path, ignore_errors=False, onerror=None)在那里 shutil.rmtreeshutil.rmtree(path, ignore_errors=False, onerror=None),shutil.rmtreeshutil.rmtree(path, ignore_errors=False, onerror=None); path是导致它失败的那个函数的参数; 并且 shutil.rmtree是由...返回的元组 shutil.rmtree(path, ignore_errors=False, onerror=None).如果shutil.rmtree为false,shutil.rmtree(path, ignore_errors=False, onerror=None)则会shutil.rmtree引发异常.

  • 这不仅会删除内容,还会删除文件夹本身.我不认为问题是什么. (231认同)
  • 因为新目录和旧目录不一样.因此,如果一个程序正在目录中,等待事情,它将从它下面拉出地毯. (29认同)
  • 只需在`rmtree`之后重新创建目录.就像`os.makedirs(dir)` (27认同)
  • @IuliusCurt 不,我在 ram 中安装了一个目录,我需要清空,不幸的是我不能删除然后重新创建它:`OSError: [Errno 16] 设备或​​资源繁忙` (11认同)
  • 您必须注意,重新创建文件夹不一定是相同的,例如,如果您将文件夹装载到泊坞窗中并删除该文件夹,则在泊坞窗内重新创建文件夹将不会导致重新创建已装载的文件夹。 (5认同)
  • 还要考虑权限、unix 中的文件 mods、所有权等。因此这个例子是危险的。 (5认同)
  • 我认为这是一个很好的答案.你为什么不删除内容和文件夹,然后重新制作文件夹? (2认同)
  • 另外,您将重置所有元数据(创建时间、上次访问时间等) (2认同)

小智 206

你可以这样做:

import os
import glob

files = glob.glob('/YOUR/PATH/*')
for f in files:
    os.remove(f)
Run Code Online (Sandbox Code Playgroud)

您当然可以在路径中使用其他过滤器,例如:/YOU/PATH/*.txt用于删除目录中的所有文本文件.

  • @Blueicefield`*`不会列出隐藏文件,我们还应该添加`glob.glob('path /.*)` (8认同)
  • 而`import sh; sh.rm(files)` 看起来确实更漂亮,如果目录中的文件超过 1024 个,您就会遇到麻烦。 (4认同)
  • 虽然删除文件列表,但我做起来似乎更简单:`import sh; sh.rm(文件)` (3认同)
  • 引发子目录异常 (2认同)

Ike*_*nez 74

扩展mhawke的答案这是我实施的.它会删除文件夹的所有内容,但不会删除文件夹本身.在Linux上使用文件,文件夹和符号链接进行测试,也可以在Windows上运行.

import os
import shutil

for root, dirs, files in os.walk('/path/to/folder'):
    for f in files:
        os.unlink(os.path.join(root, f))
    for d in dirs:
        shutil.rmtree(os.path.join(root, d))
Run Code Online (Sandbox Code Playgroud)

  • 这很接近,但os.walk和shutil.rmtree都是递归的.os.walk是不必要的,因为您只需要要清理的目录中顶层的文件和目录.只需对os.listdir中的元素使用if语句,以查看每个元素是文件还是目录.然后分别使用remove/unlink和rmtree. (7认同)
  • @MatthewAlpert但是请注意,`os.walk`不会在这里递归,因为它返回一个生成器,当您尝试前进时,以及当您完成此循环的第一次迭代时,它只会递归地查找子目录,没有任何子目录可供查看。本质上,“os.walk”只是在这里用作区分顶级文件夹和顶级文件的替代方法;没有使用递归,我们无需为此付出任何性能成本。不过,这很奇怪,我同意您建议的方法更好,因为它更明确且更具可读性。 (5认同)
  • 如果您也要删除目录,这是正确的答案。“ walk”用于分割目录和文件,必须以不同的方式处理。您也可以使用`os.listdir`,但是您必须手动检查每个条目是目录还是文件。 (2认同)

jgo*_*ers 44

使用rmtree和重新创建文件夹可以正常工作,但是在删除并立即重新创建网络驱动器上的文件夹时遇到了错误.

使用walk的建议解决方案不起作用,因为它用于rmtree删除文件夹,然后可能尝试使用os.unlink以前在这些文件夹中的文件.这会导致错误.

发布的glob解决方案还将尝试删除非空文件夹,从而导致错误.

我建议你使用:

folder_path = '/path/to/folder'
for file_object in os.listdir(folder_path):
    file_object_path = os.path.join(folder_path, file_object)
    if os.path.isfile(file_object_path) or os.path.islink(file_object_path):
        os.unlink(file_object_path)
    else:
        shutil.rmtree(file_object_path)
Run Code Online (Sandbox Code Playgroud)


Jon*_*Chu 17

这是迄今为止唯一的答案,其中:

  • 删除所有符号链接
    • 死链接
    • 指向目录的链接
    • 链接到文件
  • 删除子目录
  • 不会删除父目录

码:

for filename in os.listdir(dirpath):
    filepath = os.path.join(dirpath, filename)
    try:
        shutil.rmtree(filepath)
    except OSError:
        os.remove(filepath)
Run Code Online (Sandbox Code Playgroud)

正如许多其他答案一样,这并不会尝试调整权限以启用文件/目录的删除.


小智 15

要删除文件夹中的所有文件,我使用:

import os
for i in os.listdir():
    os.remove(i)
Run Code Online (Sandbox Code Playgroud)

  • 只是强调一下,这仅在给定目录仅包含文件的情况下才有效。如果该目录包含另一个目录,则会引发“IsADirectoryError”异常。 (10认同)
  • 这个答案在技术上并不正确。“i”仅是项目的名称,不包括目录路径。建议更正: for i in os.listdir(dir_path): os.remove(fr'{dir_path}\{i}')。 (5认同)

fmo*_*lia 14

作为oneliner:

import os

# Python 2.7
map( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) )

# Python 3+
list( map( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) ) )
Run Code Online (Sandbox Code Playgroud)

考虑文件和目录的更强大的解决方案也是(2.7):

def rm(f):
    if os.path.isdir(f): return os.rmdir(f)
    if os.path.isfile(f): return os.unlink(f)
    raise TypeError, 'must be either file or directory'

map( rm, (os.path.join( mydir,f) for f in os.listdir(mydir)) )
Run Code Online (Sandbox Code Playgroud)

  • 在Python3中,你必须将“map”包装在“list”中才能实际迭代。请参阅[http://stackoverflow.com/questions/1303347/getting-a-map-to-return-a-list-in-python-3-x](http://stackoverflow.com/questions/1303347/getting -a-map-to-return-a-list-in-python-3-x) (2认同)

Roc*_*ite 14

注意:如果有人拒绝投票给我答案,我在这里有一些解释.

  1. 每个人都喜欢简短的答案.然而,有时现实并非如此简单.
  2. 回到我的回答.我知道shutil.rmtree()可以用来删除目录树.我在自己的项目中多次使用它.但是你必须意识到目录本身也会被删除shutil.rmtree().虽然这对某些人来说可能是可以接受的,但它不是删除文件夹内容的有效答案(没有副作用).
  3. 我将向您展示副作用的一个例子.假设您有一个具有自定义所有者和模式位的目录,其中有很多内容.然后你删除它shutil.rmtree()并用它重建它os.mkdir().并且您将获得一个带有默认(继承)所有者和模式位的空目录.虽然您可能有权删除内容甚至目录,但您可能无法在目录上设置原始所有者和模式位(例如,您不是超级用户).
  4. 最后,请耐心等待并阅读代码.它长而丑陋(在视线中),但被证明是可靠和有效的(使用中).

这是一个漫长而丑陋但可靠而有效的解决方案.

它解决了其他问题无法解决的一些问题:

  • 它正确处理符号链接,包括不调用shutil.rmtree()符号链接(os.path.isdir()如果它链接到目录将传递测试;甚至os.walk()包含符号链接目录的结果).
  • 它很好地处理只读文件.

这是代码(唯一有用的功能clear_dir()):

import os
import stat
import shutil


# http://stackoverflow.com/questions/1889597/deleting-directory-in-python
def _remove_readonly(fn, path_, excinfo):
    # Handle read-only files and directories
    if fn is os.rmdir:
        os.chmod(path_, stat.S_IWRITE)
        os.rmdir(path_)
    elif fn is os.remove:
        os.lchmod(path_, stat.S_IWRITE)
        os.remove(path_)


def force_remove_file_or_symlink(path_):
    try:
        os.remove(path_)
    except OSError:
        os.lchmod(path_, stat.S_IWRITE)
        os.remove(path_)


# Code from shutil.rmtree()
def is_regular_dir(path_):
    try:
        mode = os.lstat(path_).st_mode
    except os.error:
        mode = 0
    return stat.S_ISDIR(mode)


def clear_dir(path_):
    if is_regular_dir(path_):
        # Given path is a directory, clear its content
        for name in os.listdir(path_):
            fullpath = os.path.join(path_, name)
            if is_regular_dir(fullpath):
                shutil.rmtree(fullpath, onerror=_remove_readonly)
            else:
                force_remove_file_or_symlink(fullpath)
    else:
        # Given path is a file or a symlink.
        # Raise an exception here to avoid accidentally clearing the content
        # of a symbolic linked directory.
        raise OSError("Cannot call clear_dir() on a symbolic link")
Run Code Online (Sandbox Code Playgroud)


Jac*_*Wan 9

import os
import shutil

# Gather directory contents
contents = [os.path.join(target_dir, i) for i in os.listdir(target_dir)]

# Iterate and remove each item in the appropriate manner
[os.remove(i) if os.path.isfile(i) or os.path.islink(i) else shutil.rmtree(i) for i in contents]
Run Code Online (Sandbox Code Playgroud)

之前的评论还提到在Python 3.5+中使用os.scandir.例如:

import os
import shutil

with os.scandir(target_dir) as entries:
    for entry in entries:
        if entry.is_file() or entry.is_symlink():
            os.remove(entry.path)
        elif entry.is_dir():
            shutil.rmtree(entry.path)
Run Code Online (Sandbox Code Playgroud)


Kev*_*tel 9

要删除目录及其子目录中的所有文件,而不删除文件夹本身,只需执行以下操作:

import os
mypath = "my_folder" #Enter your path here
for root, dirs, files in os.walk(mypath):
    for file in files:
        os.remove(os.path.join(root, file))
Run Code Online (Sandbox Code Playgroud)


sil*_*ttt 8

如果您使用的是 *nix 系统,为什么不利用 system 命令呢?

import os
path = 'folder/to/clean'
os.system('rm -rf %s/*' % path)
Run Code Online (Sandbox Code Playgroud)

  • 因为,如问题所述,“当前项目适用于 Windows” (4认同)
  • `os.system` + 字符串处理 + 不正确的引用 = shell 注入 (2认同)

mha*_*wke 7

你最好还是可以使用os.walk()它.

os.listdir()不区分文件和目录,你很快就会试图解除这些链接.有使用的一个很好的例子os.walk()递归删除目录在这里,以及如何使其适应你的情况提示.


Hus*_*sky 7

我感到惊讶的是,没有人提到pathlib做这项工作很棒。

如果您只想删除目录中的文件,则可以将其作为一个文件

from pathlib import Path

[f.unlink() for f in Path("/path/to/folder").glob("*") if f.is_file()] 
Run Code Online (Sandbox Code Playgroud)

要还递归地删除目录,您可以编写如下内容:

from pathlib import Path
from shutil import rmtree

for path in Path("/path/to/folder").glob("**/*"):
    if path.is_file():
        path.unlink()
    elif path.is_dir():
        rmtree(path)
Run Code Online (Sandbox Code Playgroud)

  • 以这种方式使用列表理解不是最佳实践。列表理解用于构建列表。第二种方法很好。 (8认同)
  • `.iterdir()` 而不是 `.glob(...)` 也应该可以工作。 (4认同)

Pro*_*e85 6

我曾经这样解决问题:

import shutil
import os

shutil.rmtree(dirpath)
os.mkdir(dirpath)
Run Code Online (Sandbox Code Playgroud)

  • 这与问题所要求的语义完全不同,不应被视为有效答案. (6认同)
  • 恕我直言,我认为“删除本地文件夹的内容”并不涉及删除文件夹本身。与[这个答案](http://stackoverflow.com/a/186236/590767)同样的问题,只不过得到了很多赞成票! (3认同)
  • 这就像回答"如何让函数返回Python中的数字1?"这个问题.使用def return_a_one():launch_some_nukes()返回1 (3认同)
  • 当然,语义是不同的:但是您最好将其视为解决问题的另一种方法。此解决方案解决了问题,因此非常有效。您的“ launch_some_nukes”示例与众不同:1.该解决方案比公认的解决方案更短,更容易,并且反对您引用的答案是有效的。2.在这种情况下,等效的“ launch_some_nukes”是删除并重新创建文件夹。新旧文件夹之间的区别只是索引节点号(可能与OP无关) (2认同)
  • 两者都不涉及拆除摩天大楼,然后重建您选择的高度。 (2认同)
  • 它是在拆除摩天大楼,然后重建一个完全相同的大小;) (2认同)
  • 我实际上使用了这个解决方案 - 而且它有效。好的一面是——很简单,坏的一面——有一些边缘情况。如果在该目录中打开了 shell,则删除该目录将会失败(至少在 Windows 上) - 删除文件不会导致这种情况。另外:当使用目录的相对名称(例如“temp”)时,“rmtree”将起作用,但“os.mkdir”将失败(除非您使用“./temp”)。 (2认同)

Nic*_*Bar 6

我必须从单个父目录中的 3 个单独文件夹中删除文件:

directory
   folderA
      file1
   folderB
      file2
   folderC
      file3
Run Code Online (Sandbox Code Playgroud)

这个简单的代码对我有用:(我在 Unix 上)

import os
import glob

folders = glob.glob('./path/to/parentdir/*')
for fo in folders:
  file = glob.glob(f'{fo}/*')
  for f in file:
    os.remove(f)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。


Saw*_*yer 5

我知道这是一个老线程,但我从python的官方网站上发现了一些有趣的东西.仅仅是为了分享另一个删除目录中所有内容的想法.因为在使用shutil.rmtree()时我有一些授权问题,我不想删除目录并重新创建它.原地址为http://docs.python.org/2/library/os.html#os.walk.希望可以帮助别人.

def emptydir(top):
    if(top == '/' or top == "\\"): return
    else:
        for root, dirs, files in os.walk(top, topdown=False):
            for name in files:
                os.remove(os.path.join(root, name))
            for name in dirs:
                os.rmdir(os.path.join(root, name))
Run Code Online (Sandbox Code Playgroud)


Rob*_*low 5

又一个解决方案:

import sh
sh.rm(sh.glob('/path/to/folder/*'))
Run Code Online (Sandbox Code Playgroud)

  • 请注意,“sh”不是标准库的一部分,需要从 PyPI 安装才能使用它。另外,由于这实际上在子进程中调用“rm”,因此它在不存在“rm”的 Windows 上不起作用。如果文件夹包含任何子目录,它也会引发异常。 (3认同)