shutil.rmtree
не удаляет файлы, доступные только для чтения, в Windows. Есть ли эквивалент "rm -rf" для Python? Почему, почему это такая боль?
Удаление каталога в Python
Ответы (6)
shutil.rmtree
может принимать функцию обработки ошибок, которая будет вызываться при возникновении проблемы с удалением файла. Вы можете использовать это для принудительного удаления проблемных файлов.
На основе http://mail.python.org/pipermail/tutor/2006-June/047551.html и http://techarttiki.blogspot.com/2008/08/read-only-windows-files-with-python.html:
import os
import stat
import shutil
def remove_readonly(func, path, excinfo):
os.chmod(path, stat.S_IWRITE)
func(path)
shutil.rmtree(top, onerror=remove_readonly)
(Я не тестировал этот фрагмент, но этого должно быть достаточно, чтобы вы начали)
shutil.rmtree('mypath', onerror=lambda func, path, _: (os.chmod(path, stat.S_IWRITE), func(path)))
- person Basj; 06.12.2020
Если вы импортируете win32api из PyWin32, вы можете использовать:
win32api.SetFileAttributes(path, win32con.FILE_ATTRIBUTE_NORMAL)
Чтобы файлы перестали быть доступными только для чтения.
Другой способ - определить rmtree в Windows как
rmtree = lambda path: subprocess.check_call(['cmd', '/c', 'rd', '/s', '/q', path])
Предположительно, это будет исправлено с выпуском Python 3.5 (в настоящее время - июнь 2015 года - все еще в разработке) в том смысле, что намек на это будет в документации.
Отчет об ошибке можно найти здесь. И это соответствующий набор изменений.
См. Недавно добавленный пример из документации Python 3.5:
import os, stat
import shutil
def remove_readonly(func, path, _):
"Clear the readonly bit and reattempt the removal"
os.chmod(path, stat.S_IWRITE)
func(path)
shutil.rmtree(directory, onerror=remove_readonly)
На сайте ActiveState есть комментарий, в котором говорится:
shutil.rmtree имеет свои недостатки. Хотя это правда, что вы можете использовать shutil.rmtree () во многих случаях, в некоторых случаях это не работает. Например, файлы, помеченные как доступные только для чтения в Windows, не могут быть удалены с помощью shutil.rmtree ().
Это препятствие можно преодолеть, импортировав модули win32api и win32con из PyWin32 и добавив строку типа win32api.SetFileAttributes (path, win32con.FILE_ATTRIBUTE_NORMAL) в функцию rmgeneric (). Я использовал этот подход, чтобы исправить сценарий hot-backup.py для Subversion. 1.4 так будет работать под Windows.Спасибо за рецепт.
Я не использую Windows, поэтому не могу проверить, работает это или нет.
Вот вариант того, что написал Стив, он использует тот же базовый механизм, и этот протестирован :-)
Какой пользователь запускает скрипты Python как в Windows?