Відповіді:
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 є істинним, помилки в результаті невдалого видалення будуть ігноруватися; якщо помилкові чи пропущені, такі помилки обробляються за допомогою виклику обробника, визначеного onerror, або, якщо це пропущено, вони створюють виняток.
rmtree. Likeos.makedirs(dir)
OSError: [Errno 16] Device or resource busy
Розширюючись на відповідь Мауке, це те, що я реалізував. Він видаляє весь вміст папки, але не саму папку. Тестований на 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використовується для розділення файлів dirs і файлів, з якими потрібно по-різному оброблятись. Ви також можете використовувати os.listdir, але вам доведеться перевірити, чи кожен запис є dir або файл вручну.
os.walkце не повториться тут, оскільки він повертає генератор, який тільки рекурсивно переглядає підкаталоги, коли ви намагаєтесь просунути його, і до того моменту, коли ви зробили першу ітерацію цього циклу, немає підкаталогів. зліва подивитися. По суті, os.walkпросто використовується тут як альтернативний спосіб відрізнити папки верхнього рівня від файлів верхнього рівня; рекурсія не використовується, і ми не сплачуємо за неї продуктивність. Однак це ексцентрично, і я погоджуюсь, що запропонований вами підхід кращий просто тому, що він є більш чітким і зрозумілим.
Використання 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)
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 , можливо, приємніший спосіб видалення всіх файлів, залишаючи недоторканою структуру каталогу.
Якщо припустити, temp_dirщо буде видалено, командою для одного рядка osбуде:
_ = [os.remove(os.path.join(save_dir,i)) for i in os.listdir(temp_dir)]
Примітка. Це лише 1-вкладиш для видалення файлів "Не видаляє каталоги.
Сподіваюсь, це допомагає. Дякую.
Використовуйте метод нижче, щоб видалити вміст каталогу, а не сам каталог:
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')