Відповіді:
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')