Примечания: в случае, если кто-то проголосовал за мой ответ, у меня есть кое-что объяснить здесь.
- Всем нравятся короткие и простые ответы. Однако иногда реальность не так проста.
- Вернуться к моему ответу. Я знаю,
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")