Ответы:
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))
except Exception as e:
этим гласит W0703: Catching too general exception Exception
. Есть ли более конкретное исключение, которое нужно поймать, или я должен его игнорировать?
Вы можете просто сделать это:
import os
import glob
files = glob.glob('/YOUR/PATH/*')
for f in files:
os.remove(f)
Конечно, вы можете использовать другой фильтр в вашем пути, например: /YOU/PATH/*.txt для удаления всех текстовых файлов в каталоге.
*
не будет перечислять скрытые файлы, мы также должны добавитьglob.glob('path/.*)
import sh; sh.rm(files)
import sh; sh.rm(files)
выглядит лучше, вы столкнетесь с проблемами, если в каталоге будет более 1024 файлов.
Вы можете удалить саму папку, а также все ее содержимое, используя shutil.rmtree
:
import shutil
shutil.rmtree('/path/to/folder')
shutil.rmtree(path, ignore_errors=False, onerror=None)
Удалить все дерево каталогов; путь должен указывать на каталог (но не символическую ссылку на каталог). Если ignore_errors - true, ошибки, возникшие в результате неудачного удаления, будут игнорироваться; если false или пропущено, такие ошибки обрабатываются путем вызова обработчика, указанного в onerror, или, если он пропущен, они вызывают исключение.
rmtree
. Какos.makedirs(dir)
OSError: [Errno 16] Device or resource busy
Расширяя ответ 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
это не будет повторяться, потому что он возвращает генератор, который рекурсивно просматривает только подкаталоги, когда вы пытаетесь продвинуть его, и к тому времени, как вы сделали свою первую итерацию этого цикла, подкаталогов нет. осталось посмотреть. По сути, os.walk
он используется здесь как альтернативный способ отличить папки верхнего уровня от файлов верхнего уровня; рекурсия не используется, и мы не платим за нее производительность. Это эксцентрично, и я согласен, что предлагаемый вами подход лучше, потому что он более понятен и читабелен.
С помощью 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)
os.path.isfile()
он вернется False
(потому что он следует по символическим ссылкам), и вы в конечном итоге shutil.rmtree()
вызовете символическую ссылку, которая будет вызываться OSError("Cannot call rmtree on a symbolic link")
.
islink
проверки здесь для правильной обработки символических ссылок на каталоги. Я добавил такую проверку в принятый ответ.
Эта:
Код:
for filename in os.listdir(dirpath):
filepath = os.path.join(dirpath, filename)
try:
shutil.rmtree(filepath)
except OSError:
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)
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))))
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()
):
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")
os.remove
, в отличие от rm
утилиты, рад удалить файлы только для чтения до тех пор , пока у вас есть их. Между тем, если у вас нет файла , к которому у вас есть доступ только для чтения, вы не можете удалить его или изменить его разрешения. Я не знаю ни одной ситуации в системе, где вы не сможете удалить файл только для чтения, os.remove
но сможете изменить его разрешения. Кроме того, вы используете lchmod
, который не существует ни на моем Mac, ни на Windows в соответствии с его документами. Для какой платформы предназначен этот код ?!
Я удивлен, что никто не упомянул о том, как здорово pathlib
делать эту работу.
Если вы хотите удалить только файлы в каталоге, это может быть oneliner
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 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
исключение.
Вам может быть лучше использовать os.walk()
для этого.
os.listdir()
не отличает файлы от каталогов, и вы быстро столкнетесь с проблемами, пытаясь отсоединить их. Существует хороший пример использования os.walk()
рекурсивно удалить каталог здесь , и подсказки о том , как адаптировать его к вашей ситуации.
Я использовал для решения проблемы следующим образом:
import shutil
import os
shutil.rmtree(dirpath)
os.mkdir(dirpath)
Еще одно решение:
import sh
sh.rm(sh.glob('/path/to/folder/*'))
sh
он не является частью стандартной библиотеки и требует установки из PyPI, прежде чем вы сможете его использовать. Кроме того, поскольку это фактически вызывает rm
подпроцесс, он не будет работать в Windows, где rm
его не существует. Это также вызовет исключение, если папка содержит какие-либо подкаталоги.
Я знаю, что это старая ветка, но я нашел кое-что интересное на официальном сайте 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 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))
Если вы используете систему * nix, почему бы не использовать системную команду?
import os
path = 'folder/to/clean'
os.system('rm -rf %s/*' % path)
Мне пришлось удалить файлы из 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)
Надеюсь это поможет.
Ответьте на конкретную ограниченную ситуацию: если вы хотите удалить файлы при сохранении дерева подпапок, вы можете использовать рекурсивный алгоритм:
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 , возможно, является более удачным способом удаления всех файлов, оставляя структуру каталога без изменений.
Используйте метод ниже, чтобы удалить содержимое каталога, а не сам каталог:
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)
самый простой способ удалить все файлы в папке / удалить все файлы
import os
files = os.listdir(yourFilePath)
for f in files:
os.remove(yourFilePath + f)
os.system('rm -rf folder')