Как удалить содержимое папки в Python? - PullRequest
361 голосов
/ 09 октября 2008

Как я могу удалить содержимое локальной папки в Python?

Текущий проект для Windows, но я бы тоже хотел увидеть * nix.

Ответы [ 21 ]

338 голосов
/ 09 октября 2008

Обновлено только для удаления файлов и использования метода os.path.join(), предложенного в комментариях. Если вы также хотите удалить подкаталоги, раскомментируйте оператор elif.

import os, shutil
folder = '/path/to/folder'
for the_file in os.listdir(folder):
    file_path = os.path.join(folder, the_file)
    try:
        if os.path.isfile(file_path):
            os.unlink(file_path)
        #elif os.path.isdir(file_path): shutil.rmtree(file_path)
    except Exception as e:
        print(e)
203 голосов
/ 09 октября 2008

Попробуйте модуль shutil

import shutil
shutil.rmtree('/path/to/folder')

Описание: shutil.rmtree(path, ignore_errors=False, onerror=None)

Строка документации: рекурсивно удалить дерево каталогов.

Если установлено ignore_errors, ошибки игнорируются; в противном случае, если установлено onerror, он вызывается для обработки ошибки с аргументы (func, path, exc_info) где func - это os.listdir, os.remove или os.rmdir; путь является аргументом в пользу этого функция, которая вызвала его сбой; а также exc_info - это кортеж, возвращаемый sys.exc_info(). Если ignore_errors ложь и onerror это None, исключение повышено.

Важное примечание: Имейте в виду, что shutil.rmtree() не просто удаляет содержимое целевой папки. Также удаляет саму папку.

183 голосов
/ 22 апреля 2011

Вы можете просто сделать это:

import os
import glob

files = glob.glob('/YOUR/PATH/*')
for f in files:
    os.remove(f)

Конечно, вы можете использовать другой фильтр в вашем пути, например: /YOU/PATH/*.txt для удаления всех текстовых файлов в каталоге.

69 голосов
/ 02 июля 2009

Расширяя ответ 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))
44 голосов
/ 07 июля 2011

Использование 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):
        os.unlink(file_object_path)
    else:
        shutil.rmtree(file_object_path)
15 голосов
/ 24 ноября 2013

Как вкладчик:

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

Более надежное решение для учета файлов и каталогов также будет (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)) )
14 голосов
/ 20 июля 2014

Примечания: в случае, если кто-то проголосовал за мой ответ, у меня есть кое-что объяснить здесь.

  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")
13 голосов
/ 21 сентября 2012

Это пока единственный ответ, который:

  • удаляет все символические ссылки
    • мертвых ссылок
    • ссылки на каталоги
    • ссылки на файлы
  • удаляет подкаталоги
  • не удаляет родительский каталог

Код:

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

Как и во многих других ответах, здесь не предпринимается попытка настроить разрешения, чтобы разрешить удаление файлов / каталогов.

9 голосов
/ 02 декабря 2012
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]

В предыдущем комментарии также упоминается использование os.scandir в Python 3.5+. Например:

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)
8 голосов
/ 09 октября 2008

Возможно, для этого лучше использовать os.walk().

os.listdir() не отличает файлы от каталогов, и вы быстро столкнетесь с проблемами, пытаясь отсоединить их. Есть хороший пример использования os.walk() для рекурсивного удаления каталога здесь и подсказок, как адаптировать его к вашим обстоятельствам.

...