





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))
Если вы работаете с очень большим каталогом, особенно с сетевым каталогом в Windows, и можете управлять средой, в которой работает эта программа, возможно, стоит использовать функцию Py3.5 "os.scandir (folder)" вместо listdir. После этого синтаксис сильно изменится, но реализовать его довольно просто; рад опубликовать это, если другие захотят.
Я получаю предупреждение о пиллинте с except Exception as e:, которое читается как W0703: Catching too general exception Exception. Есть ли более конкретное исключение, которое нужно уловить, или мне его игнорировать?
@JohnHany, я думаю, ты хочешь поймать OSError.
Я получаю OSError: [Errno 26] Текстовый файл занят Моя файловая структура: Медиа (например, папка в вашем коде) содержит-> 2 файла и 2 каталога, где оба каталога содержат каждый файл
Возможно, вам лучше использовать для этого os.walk().
os.listdir() не различает файлы и каталоги, и вы быстро столкнетесь с проблемами, пытаясь отсоединить их. Есть хороший пример использования os.walk() для рекурсивного удаления каталога здесь и подсказки, как адаптировать его к вашим обстоятельствам.
Вы можете удалить саму папку, а также все ее содержимое, используя shutil.rmtree:
import shutil
shutil.rmtree('/path/to/folder')
shutil.rmtree(path, ignore_errors=False, onerror=None)
Delete an entire directory tree; path must point to a directory (but not a symbolic link to a directory). If ignore_errors is true, errors resulting from failed removals will be ignored; if false or omitted, such errors are handled by calling a handler specified by onerror or, if that is omitted, they raise an exception.
Это приведет к удалению не только содержимого, но и самой папки. Я не думаю, что это вопрос.
Думаю, это хороший ответ. Почему бы вам просто не удалить содержимое и папку, а затем переделать папку?
Потому что новый каталог и старый не будут одинаковыми. Так что, если программа сидит в каталоге, ожидая чего-то, ей придется вытащить коврик из-под нее.
Также обратите внимание, что если где-то в дереве папок есть один файл, который нельзя удалить, ничего не удаляется.
Просто воссоздайте каталог после rmtree. Нравится os.makedirs(dir)
@IuliusCurt нет, у меня есть каталог, смонтированный в оперативной памяти, мне нужно очистить, и, к сожалению, я не могу просто удалить, а затем воссоздать его: OSError: [Errno 16] Device or resource busy
Вы должны отметить, что воссоздание папки не обязательно одно и то же, например, если вы монтируете папку в докере и удаляете папку, воссоздание папки внутри докера не приведет к воссозданию смонтированной папки.
Также учитывайте разрешения, модификации файлов в unix, права собственности и т. д. Поэтому этот пример опасен.
плюс вы сбросите все метаданные (время создания, время последнего доступа и т. д.)
Даже если вас не интересуют метаданные и т. д., В Windows может случайно возникнуть некоторая проблема с синхронизацией, когда, если вы выполните shutil.rmtree () сразу после os.makedirs (..., exist_ok = True), македир будет думать, что папка все еще существует, поэтому она не будет создавать папку. Однако после завершения вызова македиров папка будет удалена. Это было упомянуто в stackoverflow.com/a/6615332/848627 относительно сетевых дисков, но я видел, как это происходило и на обычном диске.
используя это, потому что os.remove() не работает, работает Mac на Big Sur
Расширяя ответ 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))
Почему «гулять», а не просто перечислять содержимое папки?
Это правильный ответ, если вы также хотите удалить каталоги. walk используется для разделения каталогов и файлов, которые должны обрабатываться по-разному. Вы также можете использовать os.listdir, но вам придется вручную проверять, является ли каждая запись каталогом или файлом.
Это близко, но и os.walk, и shutil.rmtree рекурсивны. os.walk не нужен, так как вам нужно очистить только файлы и каталоги на верхнем уровне внутри каталога. Просто используйте оператор if для элементов в os.listdir, чтобы узнать, является ли каждый из них файлом или каталогом. Затем используйте remove / unlink и rmtree соответственно.
@MatthewAlpert Обратите внимание, однако, что os.walk не будет рекурсивно здесь, потому что он возвращает генератор, который рекурсивно просматривает подкаталоги только тогда, когда вы пытаетесь его продвинуть, и к тому времени, когда вы выполните свою первую итерацию этого цикла, нет подкаталоги, оставленные для просмотра. По сути, os.walk используется здесь как альтернативный способ отличить папки верхнего уровня от файлов верхнего уровня; рекурсия не используется, и мы не платим за ее производительность. Однако это эксцентрично, и я согласен с тем, что предлагаемый вами подход лучше просто потому, что он более ясен и удобочитаем.
Вы можете просто сделать это:
import os
import glob
files = glob.glob('/YOUR/PATH/*')
for f in files:
os.remove(f)
Конечно, вы можете использовать другой фильтр в своем пути, например: /YOU/PATH/*.txt для удаления всех текстовых файлов в каталоге.
@Blueicefield * не будет отображать скрытые файлы, мы также должны добавить glob.glob('path/.*)
хотя удалить список файлов мне кажется проще: import sh; sh.rm(files)
Хотя import sh; sh.rm(files) действительно выглядит красивее, вы столкнетесь с проблемами, если в каталоге более 1024 файлов.
@satoru, как бы вы добавили это другое объединение скрытых файлов?
@satoru для расширения на другие типы файлов с помощью glob можно использовать "extend ()".
Использование rmtree и воссоздание папки может работать, но я столкнулся с ошибками при удалении и немедленном воссоздании папок на сетевых дисках.
Предлагаемое решение с использованием обхода не работает, поскольку оно использует 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)
Ваше решение также вызовет ошибку, если есть символическая ссылка на другой каталог.
@Blueicefield - Вы можете привести пример. Я тестировал в Linux, используя файл и папку с символической ссылкой, и пока не смог вызвать ошибку.
@jgoeders - если есть символическая ссылка на каталог, os.path.isfile() вернет False (потому что он следует за символическими ссылками), и вы в конечном итоге вызовете shutil.rmtree() по символической ссылке, что вызовет OSError("Cannot call rmtree on a symbolic link").
@Rockallite исправлено проверкой на islink
мое редактирование было отклонено, но я добавил if os.path.islink(file_object_path): os.unlink(file_object_path) и преобразовал if в else if.
rmtree для удаления папок, а затем может попытаться использовать os.unlink для файлов, которые ранее находились в этих папках» - this isn't what I witness using a local drive on my Mac. The generator returned from os.walk simply doesn't yield a second element if you've deleted all the folders on the first iteration. I can believe that there's some file system or environment for which this is true (e.g. a network drive), but it's definitely not a universal truth.
Также: @kevinf правильно указывает на необходимость проверки islink для правильной обработки символических ссылок на каталоги. Я добавил такую проверку к принятому ответу.
Этот:
Код:
for filename in os.listdir(dirpath):
filepath = os.path.join(dirpath, filename)
try:
shutil.rmtree(filepath)
except OSError:
os.remove(filepath)
Как и многие другие ответы, это не пытается настроить разрешения, чтобы разрешить удаление файлов / каталогов.
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)
os.path.isdir() не является допустимым способом отличить обычный каталог от символической ссылки. Вызов shutil.rmtree() по символической ссылке вызовет исключение OSError.
@Rockallite Спасибо. Ты прав. Я обновил пример.
Я знаю, что это старая ветка, но я нашел кое-что интересное на официальном сайте 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))
Раньше я решал проблему так:
import shutil
import os
shutil.rmtree(dirpath)
os.mkdir(dirpath)
Его семантика радикально отличается от того, что задается в вопросе, и его не следует рассматривать как действительный ответ.
Не понимаю вашего комментария:> «Как я могу удалить содержимое локальной папки в Python. Текущий проект предназначен для Windows, но я бы также хотел увидеть * nix.» - это вопрос. Ответ решает задачу.
С уважением, я думаю, что «Удалить содержимое локальной папки» не означает удаление самой папки. Та же проблема, что и этот ответ, за исключением того, что получил много голосов!
Это похоже на ответ на вопрос: «Как сделать так, чтобы функция в Python возвращала число 1?» с def return_a_one (): launch_some_nukes () return 1
Конечно, семантика иная: но вы также можете рассматривать это как еще один способ взглянуть на проблему. Это решение прекрасно, поскольку оно решает проблему. Есть отличие от вашего примера «launch_some_nukes»: 1. Решение короче и проще, чем принятое, и в отличие от приведенного вами ответа оно действительно. 2. Эквивалент 'launch_some_nukes' в этом случае - это удаление и воссоздание папки. Разница между старой и новой папкой - только номер inode (вероятно, не имеет отношения к OP)
Я бы сказал, что это больше похоже на типичный физический вопрос: узнать высоту небоскреба с помощью барометра: ожидаемое решение - измерить атмосферное давление внизу и вверху и рассчитать разницу в высоте по барометрической формуле Другое Решением было бы пойти к дворнику и дать ему барометр в обмен на то, что он скажет вам высоту небоскреба.
Ни то, ни другое не предполагает сноса небоскреба и последующего восстановления небоскреба любой высоты по вашему выбору.
Это скорее снос небоскреба и восстановление точно такого же размера;)
Я действительно использовал это решение - и оно работает. Из плюсов - это просто, из минусов - есть крайние случаи. Удаление каталога не удастся (по крайней мере, в Windows), если в этом каталоге открыта оболочка - удаление файлов НЕ приведет к этому. Также: при использовании относительных имен для каталога, таких как «temp», 'rmtree' будет работать, но 'os.mkdir' не будет работать (если вы не используете «./temp»).
Блестящая идея, но есть проблема, иногда она может не работать: stackoverflow.com/questions/16373747/…
как вы сохраняете права пользователя папки?
Что ж, в зависимости от ситуации это работает очень хорошо @fatuhoku, например, в моем случае я пытаюсь сделать то, что ставится под сомнение, но в зависимости от моей программы я бы подумал, если удаление и повторное создание каталога вызовет некоторые проблемы (that's on me), но это действительно нет .. так что этот ответ все еще в порядке! Зависит от того, кто читает это в Интернете, и как они думают, что этот ответ повлияет на их программу.
В качестве единственного лайнера:
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)) )
для больших операций с использованием генератора может быть несколько эффективнее map( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) )
на самом деле пытаясь использовать это, понял, что объект карты должен быть повторен, поэтому требуется вызов списка (или что-то, что будет повторяться), например list(map(os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir))))
Первый включен в ответ, второй для меня не имеет смысла. Зачем вам перебирать функцию, отображаемую на итерацию? Карта делает это.
В Python3 вам нужно обернуть map в list, чтобы выполнить итерацию. См. http://stackoverflow.com/questions/1303347/getting-a-map-to- return-a-list-in-pyt hon-3-x
Это точно не сработает, если mydir содержит хотя бы одну папку, так как unlink работает только для файлов ...
@kupsef ты прав. Я включил обходной путь для этого в свой ответ
Еще одно решение:
import sh
sh.rm(sh.glob('/path/to/folder/*'))
Обратите внимание, что sh не входит в стандартную библиотеку и его необходимо установить из PyPI, прежде чем вы сможете его использовать. Кроме того, поскольку это фактически вызывает rm в подпроцессе, он не будет работать в Windows, где rm не существует. Это также вызовет исключение, если папка содержит какие-либо подкаталоги.
Примечания: в случае, если кто-то проголосовал против моего ответа, мне есть что объяснить.
shutil.rmtree() можно использовать для удаления дерева каталогов. Я использовал его много раз в своих проектах. Но вы должны понимать, что сам каталог также будет удален shutil.rmtree(). Хотя для некоторых это может быть приемлемо, это неверный ответ для удаление содержимого папки (без побочных эффектов).shutil.rmtree() и восстанавливаете с помощью os.mkdir(). Вместо этого вы получите пустой каталог с дефолт (унаследованным) владельцем и битами режима. Хотя у вас может быть привилегия на удаление содержимого и даже каталога, вы не сможете восстановить исходные биты владельца и режима в каталоге (например, вы не суперпользователь).Вот долгое и некрасивое, но надежное и эффективное решение.
Он решает несколько проблем, которые не решаются другими респондентами:
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")
Я не понимаю, в каком контексте имеет смысл менять режим файла. На моем Mac os.remove, утилита в отличиеrm, с радостью удаляет файлы, доступные только для чтения, если они у вас есть. Между тем, если это файл, который принадлежит вам не и к которому у вас есть доступ только для чтения, вы не можете его удалить. или же изменит его права доступа. Я не знаю ни одной ситуации в какой-либо системе, когда вы не смогли бы удалить файл, доступный только для чтения, с помощью os.remove, но смогли бы изменить его разрешения. Кроме того, вы используете lchmod, которого нет ни на моем Mac, ни в Windows, согласно его документации. Для какой платформы предназначен этот код ?!
Это должно помочь, просто используя модуль ОС для вывода списка и последующего удаления!
import os
DIR = os.list('Folder')
for i in range(len(DIR)):
os.remove('Folder'+chr(92)+i)
Работал у меня, при любых проблемах дайте знать!
Ответ для ограниченной конкретной ситуации: предполагая, что вы хотите удалить файлы, поддерживая дерево вложенных папок, вы можете использовать рекурсивный алгоритм:
import os
def recursively_remove_files(f):
if os.path.isfile(f):
os.unlink(f)
elif os.path.isdir(f):
for fi in os.listdir(f):
recursively_remove_files(os.path.join(f, fi))
recursively_remove_files(my_directory)
Может немного не по теме, но думаю, многим это пригодится
Использование os.walk способом, показанным в stackoverflow.com/a/54889532/1709587, возможно, является более приятным способом удаления всех файлов, оставляя структуру каталогов нетронутой.
Я решил проблему с rmtreemakedirs, добавив time.sleep() между:
if os.path.isdir(folder_location):
shutil.rmtree(folder_location)
time.sleep(.5)
os.makedirs(folder_location, 0o777)
Если вы используете систему * nix, почему бы не использовать системную команду?
import os
path = 'folder/to/clean'
os.system('rm -rf %s/*' % path)
Потому что, как указано в вопросе, «Текущий проект предназначен для Windows»
@soxwithMonica нельзя адаптировать эту команду для синтаксиса терминала Windows?
@Jivan уверен, что может.
Ой. Опасно запускать с -rf. Если есть ошибка в пути ... может закончиться удалением важных файлов.
Используйте описанный ниже метод для удаления содержимого каталога, а не самого каталога:
import os
import shutil
def remove_contents(path):
for c in os.listdir(path):
full_path = os.path.join(path, c)
if os.path.isfile(full_path):
os.remove(full_path)
else:
shutil.rmtree(full_path)
@FabioSpaghetti Negative
спасибо, Амир, я ищу решение, которое находит определенную папку во всех подкаталогах корневого каталога и удаляет содержимое этой папки
Это не добавляет ничего нового, чего не было в принятом ответе за несколько лет до того, как вы его опубликовали.
Чтобы удалить все файлы внутри каталога, а также его подкаталоги, не удаляя сами папки, просто сделайте следующее:
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))
Я удивлен, что никто не упомянул о замечательном pathlib для этой работы.
Если вы хотите удалить только файлы в каталоге, это может быть единственная инструкция.
from pathlib import Path
[f.unlink() for f in Path("/path/to/folder").glob("*") if f.is_file()]
Чтобы также рекурсивно удалять каталоги, вы можете написать что-то вроде этого:
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)
.iterdir() вместо .glob(...) тоже должен работать.
Довольно интуитивно понятный способ сделать это:
import shutil, os
def remove_folder_contents(path):
shutil.rmtree(path)
os.makedirs(path)
remove_folder_contents('/path/to/folder')
самый простой способ удалить все файлы в папке / удалить все файлы
import os
files = os.listdir(yourFilePath)
for f in files:
os.remove(yourFilePath + f)
Не работает, если есть подкаталоги.
Что ж, я думаю, что этот код работает. Он не удалит папку, и вы можете использовать этот код для удаления файлов с определенным расширением.
import os
import glob
files = glob.glob(r'path/*')
for items in files:
os.remove(items)
Мне пришлось удалить файлы из 3 отдельных папок внутри единственного родительского каталога:
directory
folderA
file1
folderB
file2
folderC
file3
Этот простой код помог мне: (Я использую 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)
Надеюсь это поможет.
для * nix, если честно, я бы просто использовал
os.system('rm -rf folder')