Как удалить / удалить папку, которая не пуста с Python?



Я получаю ошибку "доступ запрещен", когда я пытаюсь удалить папку, которая не пуста. Я использовал следующую команду в моей попытке:os.remove("/folder_name").



каков наиболее эффективный способ удаления / удаления папки / каталога, которая не пуста?

985   15  

15 ответов:

import shutil

shutil.rmtree('/folder_name')

стандартные библиотеки: shutil.rmtree.

конструкция rmtree не на деревьях папок, содержащих файлы только для чтения. Если вы хотите удалить папку независимо от того, содержит ли она файлы только для чтения, используйте

shutil.rmtree('/folder_name', ignore_errors=True)

С документы python on os.walk():

# Delete everything reachable from the directory named in 'top',
# assuming there are no symbolic links.
# CAUTION:  This is dangerous!  For example, if top == '/', it
# could delete all your disk files.
import os
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 shutil
shutil.rmtree(dest, ignore_errors=True)

из Python 3.4 вы можете использовать :

import pathlib

def delete_folder(pth) :
    for sub in pth.iterdir() :
        if sub.is_dir() :
            delete_folder(sub)
        else :
            sub.unlink()
    pth.rmdir() # if you just want to delete dir content, remove this line

здесь pth это pathlib.Path экземпляра. Хорошо, но не может быть самым быстрым.

import os
import stat
import shutil

def errorRemoveReadonly(func, path, exc):
    excvalue = exc[1]
    if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
        # change the file to be readable,writable,executable: 0777
        os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)  
        # retry
        func(path)
    else:
        # raiseenter code here

shutil.rmtree(path, ignore_errors=False, onerror=errorRemoveReadonly) 

если ignore_errors установлен, ошибки игнорируются; в противном случае, если onerror установлен, он вызывается для обработки ошибки с аргументами (func, path, exc_info), где func-ОС.listdir, os.удалить, или ОС.команда rmdir; пути является аргументом этой функции, что привело к сбою; и exc_info кортеж возвращает функция sys.exc_info (). Если ignore_errors имеет значение false, а onerror-None, возникает исключение.введите код здесь

Если вы уверены, что хотите удалить все дерево dir, и больше не заинтересованы в содержании dir, то ползать по всему дереву dir-это глупость... просто вызовите собственную команду ОС из python, чтобы сделать это. Это будет быстрее, эффективнее и меньше памяти.

RMDIR c:\blah /s /q 

или * nix

rm -rf /home/whatever 

в python код будет выглядеть так..

import sys
import os

mswindows = (sys.platform == "win32")

def getstatusoutput(cmd):
    """Return (status, output) of executing cmd in a shell."""
    if not mswindows:
        return commands.getstatusoutput(cmd)
    pipe = os.popen(cmd + ' 2>&1', 'r')
    text = pipe.read()
    sts = pipe.close()
    if sts is None: sts = 0
    if text[-1:] == '\n': text = text[:-1]
    return sts, text


def deleteDir(path):
    """deletes the path entirely"""
    if mswindows: 
        cmd = "RMDIR "+ path +" /s /q"
    else:
        cmd = "rm -rf "+path
    result = getstatusoutput(cmd)
    if(result[0]!=0):
        raise RuntimeError(result[1])

база на ответ kkubasik, проверьте, существует ли папка перед удалением, более надежная

import shutil
def remove_folder(path):
    # check if folder exists
    if os.path.exists(path):
         # remove if exists
         shutil.rmtree(path)
remove_folder("/folder_name")

от docs.python.org:

в этом примере показано, как удалить дерево каталогов в Windows, где некоторые файлы только для чтения бит. Он использует метод onerror обратный вызов для очистки бита только для чтения и повторной установки remove. Любой последующий сбой будет распространяться.

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)

Если вы не хотите использовать

просто некоторые параметры python 3.5 для завершения ответов выше. (Мне бы очень хотелось найти их здесь).

import os
import shutil
from send2trash import send2trash # (shutil delete permanently)

удалить папку, если она пуста

root = r"C:\Users\Me\Desktop\test"   
for dir, subdirs, files in os.walk(root):   
    if subdirs == [] and files == []:
           send2trash(dir)
           print(dir, ": folder removed")

удалить папку если она содержит этот файл

    elif subdirs == [] and len(files) == 1: # if contains no sub folder and only 1 file 
        if files[0]== "desktop.ini" or:  
            send2trash(dir)
            print(dir, ": folder removed")
        else:
            print(dir)

удалить папку, если она содержит только .сто или .txt файл(ы)

    elif subdirs == []: #if dir doesn’t contains subdirectory
        ext = (".srt", ".txt")
        contains_other_ext=0
        for file in files:
            if not file.endswith(ext):  
                contains_other_ext=True
        if contains_other_ext== 0:
                send2trash(dir)
                print(dir, ": dir deleted")

удалить папку, если ее размер меньше 400 КБ:

def get_tree_size(path):
    """Return total size of files in given path and subdirs."""
    total = 0
    for entry in os.scandir(path):
        if entry.is_dir(follow_symlinks=False):
            total += get_tree_size(entry.path)
        else:
            total += entry.stat(follow_symlinks=False).st_size
    return total


for dir, subdirs, files in os.walk(root):   
    If get_tree_size(dir) < 400000:  # ≈ 400kb
        send2trash(dir)
    print(dir, "dir deleted")

вы можете использовать ОС.системная команда для простоты:

import os
os.system("rm -rf dirname")

как очевидно, он фактически вызывает системный терминал для выполнения этой задачи.

чтобы удалить папку, даже если она может не существовать (избегая состояния гонки в ответ Чарльза Чоу) но все равно есть ошибки, когда другие вещи идут не так (например, проблемы с разрешением, ошибка чтения диска, файл не является каталогом)

Для Python 3.x:

import shutil

def ignore_absent_file(func, path, exc_inf):
    except_instance = exc_inf[1]
    if isinstance(except_instance, FileNotFoundError):
        return
    raise except_instance

shutil.rmtree(dir_to_delete, onerror=ignore_absent_file)

код Python 2.7 почти такой же:

import shutil
import errno

def ignore_absent_file(func, path, exc_inf):
    except_instance = exc_inf[1]
    if isinstance(except_instance, OSError) and \
        except_instance.errno == errno.ENOENT:
        return
    raise except_instance

shutil.rmtree(dir_to_delete, onerror=ignore_absent_file)
def deleteDir(dirPath):
    deleteFiles = []
    deleteDirs = []
    for root, dirs, files in os.walk(dirPath):
        for f in files:
            deleteFiles.append(os.path.join(root, f))
        for d in dirs:
            deleteDirs.append(os.path.join(root, d))
    for f in deleteFiles:
        os.remove(f)
    for d in deleteDirs:
        os.rmdir(d)
    os.rmdir(dirPath)

Я нашел очень простой способ, чтобы удалить все папка (даже не пустая) или файла о ОС WINDOWS.

os.system('powershell.exe  rmdir -r D:\workspace\Branches\*%s* -Force' %CANDIDATE_BRANCH)

С ОС.прогулка я бы предложил решение, которое состоит из 3 однострочных вызовов Python:

python -c "import sys; import os; [os.chmod(os.path.join(rs,d), 0o777) for rs,ds,fs in os.walk(_path_) for d in ds]"
python -c "import sys; import os; [os.chmod(os.path.join(rs,f), 0o777) for rs,ds,fs in os.walk(_path_) for f in fs]"
python -c "import os; import shutil; shutil.rmtree(_path_, ignore_errors=False)"

первый скрипт chmod все подкаталоги, второй скрипт chmod все файлы. Затем третий сценарий удаляет все без каких-либо препятствий.

Я проверил это из "сценария оболочки" в задании Дженкинса (я не хотел хранить новый скрипт Python в SCM, поэтому искал однострочное решение), и он работал для Linux и Windows.

Comments

    Ничего не найдено.