Удаление каталога в Python

shutil.rmtree не удаляет файлы, доступные только для чтения, в Windows. Есть ли эквивалент "rm -rf" для Python? Почему, почему это такая боль?


person kevin cline    schedule 11.12.2009    source источник
comment
Почему, почему это такая боль? Возможно, никто не потратил пять минут на то, чтобы сообщить об ошибке на bugs.python.org ... первое! Просто говорю'.   -  person Jason Orendorff    schedule 11.12.2009
comment
Я знаю, что опаздываю на вечеринку, но я только что подал bugs.python.org/issue22040   -  person Paul Moore    schedule 22.07.2014


Ответы (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)

(Я не тестировал этот фрагмент, но этого должно быть достаточно, чтобы вы начали)

person Steve Losh    schedule 11.12.2009
comment
Это сработало для меня как шарм, даже в модульных тестах Python. Спасибо! - person Lemon Calamitous; 11.02.2019
comment
Однострочный: 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)

Чтобы файлы перестали быть доступными только для чтения.

person Paul    schedule 11.12.2009

Другой способ - определить rmtree в Windows как

rmtree = lambda path: subprocess.check_call(['cmd', '/c', 'rd', '/s', '/q', path])
person asmeurer    schedule 12.09.2014

Предположительно, это будет исправлено с выпуском 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)
person mozzbozz    schedule 21.01.2015

На сайте 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, поэтому не могу проверить, работает это или нет.

person ire_and_curses    schedule 11.12.2009

Вот вариант того, что написал Стив, он использует тот же базовый механизм, и этот протестирован :-)

Какой пользователь запускает скрипты Python как в Windows?

person ThomasH    schedule 11.12.2009