Если вы работаете с очень большим каталогом, особенно с сетевым каталогом в Windows, и вы можете контролировать среду, в которой работает эта программа, возможно, стоит использовать функцию os.scandir (folder) в Py3.5 вместо listdir. Синтаксис после этого совсем другой, но довольно простой в реализации; рад опубликовать это, если другие хотят.
Майкл Скотт Катберт
Я получаю предупреждение Pylint с except Exception as e:этим гласит W0703: Catching too general exception Exception. Есть ли более конкретное исключение, которое нужно поймать, или я должен его игнорировать?
Джон Хани
7
@JohnHany, я думаю, ты хочешь поймать OSError.
MikeB
246
Вы можете просто сделать это:
import os
import glob
files = glob.glob('/YOUR/PATH/*')for f in files:
os.remove(f)
Конечно, вы можете использовать другой фильтр в вашем пути, например: /YOU/PATH/*.txt для удаления всех текстовых файлов в каталоге.
Удалить все дерево каталогов; путь должен указывать на каталог (но не символическую ссылку на каталог). Если ignore_errors - true, ошибки, возникшие в результате неудачного удаления, будут игнорироваться; если false или пропущено, такие ошибки обрабатываются путем вызова обработчика, указанного в onerror, или, если он пропущен, они вызывают исключение.
Это приведет к удалению не только содержимого, но и самой папки. Я не думаю, что это вопрос.
Икер Хименес
3
Я думаю, что это хороший ответ. Почему бы вам просто не удалить содержимое и папку, а затем переделать папку?
cssndrx
42
Потому что новый каталог и старый не будут совпадать. Так что, если программа сидит в каталоге, ожидая чего-то, из-под нее вытащит коврик.
Майк Купер
30
Просто создайте каталог после rmtree. Какos.makedirs(dir)
Юлий Курт
3
@IuliusCurt нет, у меня есть каталог, смонтированный в оперативной памяти, который мне нужно очистить, и, к сожалению, я не могу просто удалить, а затем заново создать его:OSError: [Errno 16] Device or resource busy
Arnaud P
80
Расширяя ответ 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))
Почему "ходить", а не просто список содержимого папки?
Дон
2
Это правильный ответ, если вы также хотите удалить каталоги. walkиспользуется для разделения файлов и каталогов, которые должны обрабатываться по-разному. Вы также можете использовать os.listdir, но вам придется проверять, является ли каждая запись вручную или файлом.
Дкаминс
7
Это близко, но и os.walk, и shutil.rmtree являются рекурсивными. os.walk не нужен, поскольку для очистки вам нужны только файлы и каталоги верхнего уровня внутри каталога. Просто используйте оператор if для элементов в os.listdir, чтобы увидеть, является ли каждый из них файлом или каталогом. Затем используйте remove / unlink и rmtree соответственно.
Мэтью Альперт
1
@MatthewAlpert Обратите внимание, что здесь os.walkэто не будет повторяться, потому что он возвращает генератор, который рекурсивно просматривает только подкаталоги, когда вы пытаетесь продвинуть его, и к тому времени, как вы сделали свою первую итерацию этого цикла, подкаталогов нет. осталось посмотреть. По сути, os.walkон используется здесь как альтернативный способ отличить папки верхнего уровня от файлов верхнего уровня; рекурсия не используется, и мы не платим за нее производительность. Это эксцентрично, и я согласен, что предлагаемый вами подход лучше, потому что он более понятен и читабелен.
Марк Амери
47
С помощью rmtree и воссоздание папки может работать, но я столкнулся с ошибками при удалении и немедленном воссоздании папок на сетевых дисках.
Предлагаемое решение с использованием Walk не работает, поскольку оно использует rmtreeдля удаления папок, а затем может попытаться использовать os.unlinkфайлы, которые ранее были в этих папках. Это вызывает ошибку.
Размещенное globрешение также попытается удалить непустые папки, что приведет к ошибкам.
Ваше решение также вызовет ошибку, если есть символическая ссылка на другой каталог.
Blueicefield
@Blueicefield - Можете ли вы привести пример. Я тестировал в Linux, используя символические ссылки на файл и папку, и пока не смог вызвать ошибку.
jgoeders
@jgoeders - Если есть символическая ссылка на каталог, os.path.isfile()он вернется False(потому что он следует по символическим ссылкам), и вы в конечном итоге shutil.rmtree()вызовете символическую ссылку, которая будет вызываться OSError("Cannot call rmtree on a symbolic link").
Rockallite
1
@Rockallite исправлено проверкой на islink
kevinf
1
Также: @kevinf правильно указывать на необходимость islinkпроверки здесь для правильной обработки символических ссылок на каталоги. Я добавил такую проверку в принятый ответ.
Марк Амери
20
Эта:
удаляет все символические ссылки
мертвые ссылки
ссылки на каталоги
ссылки на файлы
удаляет подкаталоги
не удаляет родительский каталог
Код:
for filename in os.listdir(dirpath):
filepath = os.path.join(dirpath, filename)try:
shutil.rmtree(filepath)exceptOSError:
os.remove(filepath)
Как и многие другие ответы, это не пытается настроить разрешения, чтобы включить удаление файлов / каталогов.
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)raiseTypeError,'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)) )
user25064
фактически пытаясь использовать это, понял, что объект карты должен быть повторен, поэтому требуется вызов списка (или что-то, что будет повторяться), напримерlist(map(os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir))))
user25064
Первый включен в ответ, второй не имеет смысла для меня. Почему вы должны перебирать функцию, сопоставленную с итерируемой? Карта делает это.
Это однозначно не будет работать, если «mydir» содержит хотя бы одну папку, поскольку unlink работает только для файлов ...
kupsef
14
Примечания: если кто-то проголосовал за мой ответ, у меня есть кое-что объяснить здесь.
Всем нравятся короткие и простые ответы. Однако иногда реальность не так проста.
Вернуться к моему ответу. Я знаю, 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-pythondef _remove_readonly(fn, path_, excinfo):# Handle read-only files and directoriesif 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_)exceptOSError:
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 =0return stat.S_ISDIR(mode)def clear_dir(path_):if is_regular_dir(path_):# Given path is a directory, clear its contentfor 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.raiseOSError("Cannot call clear_dir() on a symbolic link")
Я не понимаю, в каком контексте изменение режима файла имеет смысл. На моем Mac, os.remove, в отличие от rmутилиты, рад удалить файлы только для чтения до тех пор , пока у вас есть их. Между тем, если у вас нет файла , к которому у вас есть доступ только для чтения, вы не можете удалить его или изменить его разрешения. Я не знаю ни одной ситуации в системе, где вы не сможете удалить файл только для чтения, os.removeно сможете изменить его разрешения. Кроме того, вы используете lchmod, который не существует ни на моем Mac, ни на Windows в соответствии с его документами. Для какой платформы предназначен этот код ?!
Марк Амери
14
Я удивлен, что никто не упомянул о том, как здорово pathlibделать эту работу.
Если вы хотите удалить только файлы в каталоге, это может быть oneliner
from pathlib importPath[f.unlink()for f inPath("/path/to/folder").glob("*")if f.is_file()]
Также для рекурсивного удаления каталогов вы можете написать что-то вроде этого:
from pathlib importPathfrom shutil import rmtree
for path inPath("/path/to/folder").glob("**/*"):if path.is_file():
path.unlink()elif path.is_dir():
rmtree(path)
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
@ Rockalite Спасибо. Вы правы. Я обновил пример.
Джейкоб Ван
8
Вам может быть лучше использовать os.walk()для этого.
os.listdir()не отличает файлы от каталогов, и вы быстро столкнетесь с проблемами, пытаясь отсоединить их. Существует хороший пример использования os.walk()рекурсивно удалить каталог здесь , и подсказки о том , как адаптировать его к вашей ситуации.
Это имеет радикально отличную семантику от того, что задает вопрос, и не должно рассматриваться как правильный ответ.
фатухоку
1
С уважением, я думаю, что «Удалить содержимое локальной папки» не включает удаление самой папки. Та же проблема, что и в этом ответе , за исключением того, что получено много голосов!
фатухоку
3
Это все равно что ответить на вопрос «Как заставить функцию вернуть число 1 в Python?» с def return_a_one (): launch_some_nukes () возврат 1
фатухоку
2
Конечно, семантика другая: но вы могли бы также рассмотреть это как другой способ взглянуть на проблему. Это решение совершенно справедливо, поскольку оно решает проблему. В вашем примере launch_some_nukes есть различие: 1. Решение короче и проще принятого, и в отличие от приведенного вами ответа оно действительно. 2. эквивалентом 'launch_some_nukes' в этом случае является удаление и воссоздание папки. Разница между старой и новой папками заключается только в номере инода (вероятно, не имеет значения для OP)
ProfHase85
2
Это скорее снос небоскреба и восстановление одного и того же размера;)
Обратите внимание, что shон не является частью стандартной библиотеки и требует установки из PyPI, прежде чем вы сможете его использовать. Кроме того, поскольку это фактически вызывает rmподпроцесс, он не будет работать в Windows, где rmего не существует. Это также вызовет исключение, если папка содержит какие-либо подкаталоги.
Марк Амери
5
Я знаю, что это старая ветка, но я нашел кое-что интересное на официальном сайте python. Просто для обмена другой идеей для удаления всего содержимого в каталоге. Потому что у меня есть некоторые проблемы с авторизацией при использовании shutil.rmtree (), и я не хочу удалять каталог и создавать его заново. Оригинал адреса: http://docs.python.org/2/library/os.html#os.walk . Надеюсь, что это может помочь кому-то.
def emptydir(top):if(top =='/'or top =="\\"):returnelse: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 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 , возможно, является более удачным способом удаления всех файлов, оставляя структуру каталога без изменений.
Марк Амери
-1
Предполагая temp_dirудаление, однострочная команда osбудет:
_ =[os.remove(os.path.join(save_dir,i))for i in os.listdir(temp_dir)]
Примечание. Это всего лишь 1 строка для удаления файлов «Не удаляет каталоги.
os.system('rm -rf folder')
Ответы:
источник
except Exception as e:
этим гласитW0703: Catching too general exception Exception
. Есть ли более конкретное исключение, которое нужно поймать, или я должен его игнорировать?Вы можете просто сделать это:
Конечно, вы можете использовать другой фильтр в вашем пути, например: /YOU/PATH/*.txt для удаления всех текстовых файлов в каталоге.
источник
*
не будет перечислять скрытые файлы, мы также должны добавитьglob.glob('path/.*)
import sh; sh.rm(files)
import sh; sh.rm(files)
выглядит лучше, вы столкнетесь с проблемами, если в каталоге будет более 1024 файлов.Вы можете удалить саму папку, а также все ее содержимое, используя
shutil.rmtree
:источник
rmtree
. Какos.makedirs(dir)
OSError: [Errno 16] Device or resource busy
Расширяя ответ mhawke, это то, что я реализовал. Он удаляет все содержимое папки, но не саму папку. Протестировано на Linux с файлами, папками и символическими ссылками, должно работать и на Windows.
источник
walk
используется для разделения файлов и каталогов, которые должны обрабатываться по-разному. Вы также можете использоватьos.listdir
, но вам придется проверять, является ли каждая запись вручную или файлом.os.walk
это не будет повторяться, потому что он возвращает генератор, который рекурсивно просматривает только подкаталоги, когда вы пытаетесь продвинуть его, и к тому времени, как вы сделали свою первую итерацию этого цикла, подкаталогов нет. осталось посмотреть. По сути,os.walk
он используется здесь как альтернативный способ отличить папки верхнего уровня от файлов верхнего уровня; рекурсия не используется, и мы не платим за нее производительность. Это эксцентрично, и я согласен, что предлагаемый вами подход лучше, потому что он более понятен и читабелен.С помощью
rmtree
и воссоздание папки может работать, но я столкнулся с ошибками при удалении и немедленном воссоздании папок на сетевых дисках.Предлагаемое решение с использованием Walk не работает, поскольку оно использует
rmtree
для удаления папок, а затем может попытаться использоватьos.unlink
файлы, которые ранее были в этих папках. Это вызывает ошибку.Размещенное
glob
решение также попытается удалить непустые папки, что приведет к ошибкам.Я предлагаю вам использовать:
источник
os.path.isfile()
он вернетсяFalse
(потому что он следует по символическим ссылкам), и вы в конечном итогеshutil.rmtree()
вызовете символическую ссылку, которая будет вызыватьсяOSError("Cannot call rmtree on a symbolic link")
.islink
проверки здесь для правильной обработки символических ссылок на каталоги. Я добавил такую проверку в принятый ответ.Эта:
Код:
Как и многие другие ответы, это не пытается настроить разрешения, чтобы включить удаление файлов / каталогов.
источник
Как вкладчик:
Более надежное решение для учета файлов и каталогов также будет (2.7):
источник
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))))
map
вlist
на самом деле итерацию. См http://stackoverflow.com/questions/1303347/getting-a-map-to-return-a-list-in-python-3-xПримечания: если кто-то проголосовал за мой ответ, у меня есть кое-что объяснить здесь.
shutil.rmtree()
может быть использован для удаления дерева каталогов. Я использовал это много раз в моих собственных проектах. Но вы должны понимать, что сам каталог также будет удаленshutil.rmtree()
. Хотя это может быть приемлемо для некоторых, это не правильный ответ для удаления содержимого папки (без побочных эффектов) .shutil.rmtree()
и восстанавливаете его с помощьюos.mkdir()
. И вместо этого вы получите пустой каталог с битами по умолчанию (унаследованными) владельца и режима. Несмотря на то, что у вас может быть право удалять содержимое и даже каталог, вы не сможете установить первоначальный бит владельца и режима в каталог (например, вы не являетесь суперпользователем).Вот длинное и некрасивое, но надежное и эффективное решение.
Это решает несколько проблем, которые не решаются другими ответчиками:
shutil.rmtree()
символическую ссылку (которая пройдетos.path.isdir()
тест, если она ссылается на каталог; даже результатos.walk()
содержит также символические связанные каталоги).Вот код (единственная полезная функция
clear_dir()
):источник
os.remove
, в отличие отrm
утилиты, рад удалить файлы только для чтения до тех пор , пока у вас есть их. Между тем, если у вас нет файла , к которому у вас есть доступ только для чтения, вы не можете удалить его или изменить его разрешения. Я не знаю ни одной ситуации в системе, где вы не сможете удалить файл только для чтения,os.remove
но сможете изменить его разрешения. Кроме того, вы используетеlchmod
, который не существует ни на моем Mac, ни на Windows в соответствии с его документами. Для какой платформы предназначен этот код ?!Я удивлен, что никто не упомянул о том, как здорово
pathlib
делать эту работу.Если вы хотите удалить только файлы в каталоге, это может быть oneliner
Также для рекурсивного удаления каталогов вы можете написать что-то вроде этого:
источник
.iterdir()
а не.glob(...)
должно также работать.В предыдущем комментарии также упоминается использование os.scandir в Python 3.5+. Например:
источник
os.path.isdir()
недопустимый способ различать обычный каталог и символическую ссылку. Обращениеshutil.rmtree()
по символической ссылке вызоветOSError
исключение.Вам может быть лучше использовать
os.walk()
для этого.os.listdir()
не отличает файлы от каталогов, и вы быстро столкнетесь с проблемами, пытаясь отсоединить их. Существует хороший пример использованияos.walk()
рекурсивно удалить каталог здесь , и подсказки о том , как адаптировать его к вашей ситуации.источник
Я использовал для решения проблемы следующим образом:
источник
Еще одно решение:
источник
sh
он не является частью стандартной библиотеки и требует установки из PyPI, прежде чем вы сможете его использовать. Кроме того, поскольку это фактически вызываетrm
подпроцесс, он не будет работать в Windows, гдеrm
его не существует. Это также вызовет исключение, если папка содержит какие-либо подкаталоги.Я знаю, что это старая ветка, но я нашел кое-что интересное на официальном сайте python. Просто для обмена другой идеей для удаления всего содержимого в каталоге. Потому что у меня есть некоторые проблемы с авторизацией при использовании shutil.rmtree (), и я не хочу удалять каталог и создавать его заново. Оригинал адреса: http://docs.python.org/2/library/os.html#os.walk . Надеюсь, что это может помочь кому-то.
источник
Чтобы удалить все файлы внутри каталога, а также его подкаталогов, не удаляя сами папки, просто сделайте это:
источник
Если вы используете систему * nix, почему бы не использовать системную команду?
источник
Довольно интуитивный способ сделать это:
источник
Ну, я думаю, что этот код работает. Папка не будет удалена, и вы можете использовать этот код для удаления файлов с определенным расширением.
источник
Мне пришлось удалить файлы из 3 отдельных папок внутри одного родительского каталога:
Этот простой код помог мне (я в Unix)
Надеюсь это поможет.
источник
Я решил проблему с
rmtree
makedirs
добавлениемtime.sleep()
между:источник
Ответьте на конкретную ограниченную ситуацию: если вы хотите удалить файлы при сохранении дерева подпапок, вы можете использовать рекурсивный алгоритм:
Может быть, немного не по теме, но я думаю, что многие найдут это полезным
источник
os.walk
способом, показанным на stackoverflow.com/a/54889532/1709587 , возможно, является более удачным способом удаления всех файлов, оставляя структуру каталога без изменений.Предполагая
temp_dir
удаление, однострочная командаos
будет:Примечание. Это всего лишь 1 строка для удаления файлов «Не удаляет каталоги.
Надеюсь это поможет. Спасибо.
источник
Используйте метод ниже, чтобы удалить содержимое каталога, а не сам каталог:
источник
самый простой способ удалить все файлы в папке / удалить все файлы
источник
Это должно сделать трюк, просто используя модуль OS, чтобы вывести список, а затем удалить!
Работал на меня, любые проблемы, дайте мне знать!
источник