¿Cómo elimino / borro una carpeta que no está vacía con Python?

Recibo un error de ‘acceso denegado’ cuando bash eliminar una carpeta que no está vacía. Utilicé el siguiente comando en mi bash: os.remove("/folder_name") .

¿Cuál es la forma más efectiva de eliminar / eliminar una carpeta / directorio que no está vacío?

 import shutil shutil.rmtree('/folder_name') 

Referencia de la biblioteca estándar: shutil.rmtree .

Por diseño, rmtree falla en los árboles de carpetas que contienen archivos de solo lectura. Si desea que la carpeta se elimine independientemente de si contiene archivos de solo lectura, utilice

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

De los documentos de python en 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) 

desde Python 3.4 puedes usar:

 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 

donde pth es una instancia de pathlib.Path . Agradable, pero puede que no sea el más rápido.

 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) 

Si se establece ignore_errors, los errores se ignoran; de lo contrario, si se establece onerror, se llama para manejar el error con argumentos (func, path, exc_info) donde func es os.listdir, os.remove o os.rmdir; ruta es el argumento de esa función que hizo que fallara; y exc_info es una tupla devuelta por sys.exc_info (). Si ignore_errors es falso y onerror es Ninguno, se genera una excepción. Ingrese el código aquí

Si está seguro, desea eliminar todo el árbol de direcciones y no está más interesado en el contenido de las direcciones, entonces rastrear todo el árbol de direcciones es una estupidez … solo llame al comando del sistema operativo nativo desde Python para hacerlo. Será más rápido, eficiente y consumirá menos memoria.

 RMDIR c:\blah /s /q 

o * nix

 rm -rf /home/whatever 

En python, el código se verá como …

 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]) 

De docs.python.org :

Este ejemplo muestra cómo eliminar un árbol de directorios en Windows donde algunos de los archivos tienen su conjunto de bits de solo lectura. Utiliza la callback de onerror para borrar el bit de solo lectura y volver a intentar eliminar. Cualquier fallo posterior se propagará.

 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) 

Solo algunas opciones de python 3.5 para completar las respuestas anteriores. (Me hubiera encantado encontrarlos aquí).

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

Eliminar carpeta si está vacía

 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") 

Eliminar también la carpeta si contiene este archivo.

  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) 

eliminar carpeta si contiene solo archivos .srt o .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") 

Eliminar carpeta si su tamaño es inferior a 400kb:

 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") 

Base en la respuesta de kkubasik, verifique si la carpeta existe antes de eliminar, más robusta

 import shutil def remove_folder(path): # check if folder exists if os.path.exists(path): # remove if exists shutil.rmtree(path) else: # throw your exception to handle this special scenario raise XXError("your exception") remove_folder("/folder_name") 

Si no quiere usar el módulo de shutil , solo puede usar el módulo os .

 from os import listdir, rmdir, remove for i in listdir(directoryToRemove): os.remove(os.path.join(directoryToRemove, i)) rmdir(directoryToRemove) # Now the directory is empty of files 

Puedes usar el comando os.system por simplicidad:

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

Como es obvio, en realidad invoca el terminal del sistema para realizar esta tarea.

 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) 

Para eliminar una carpeta aunque no exista (evitando la condición de carrera en la respuesta de Charles Chow ) pero aún tenga errores cuando otras cosas van mal (por ejemplo, problemas de permisos, error de lectura del disco, el archivo no es un directorio)

Para 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) 

El código de Python 2.7 es casi el mismo:

 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) 

Con os.walk propondría la solución que consta de 3 llamadas de Python de una sola línea:

 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)" 

El primer script chmod’s todos los subdirectorios, el segundo script chmod’s todos los archivos. Luego el tercer script elimina todo sin impedimentos.

He probado esto desde el “Shell Script” en un trabajo de Jenkins (no quería almacenar un nuevo script de Python en SCM, por eso busqué una solución de una línea) y funcionó para Linux y Windows.

Diez años más tarde y usando Python 3.7 y Linux, todavía hay diferentes maneras de hacer esto:

 import subprocess from pathlib import Path #using pathlib.Path path = Path('/path/to/your/dir') subprocess.run(["rm", "-rf", str(path)]) #using strings path = "/path/to/your/dir" subprocess.run(["rm", "-rf", path]) 

Esencialmente, está usando el módulo de subproceso de Python para ejecutar el script bash $ rm -rf '/path/to/your/dir como si estuviera usando el terminal para realizar la misma tarea. No es completamente Python, pero lo hace.

La razón por la que pathlib.Path ejemplo pathlib.Path es porque, en mi experiencia, es muy útil cuando se trata de muchos caminos que cambian. Los pasos adicionales de importar el módulo pathlib.Path y convertir los resultados finales en cadenas suelen ser un costo menor para el tiempo de desarrollo. Sería conveniente que Path.rmdir() viniera con una opción arg para manejar explícitamente direcciones no vacías.

He encontrado una manera muy fácil de eliminar cualquier carpeta (incluso NO vacía) o archivo en el sistema operativo WINDOWS .

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

Para Windows, si el directorio no está vacío, y tiene archivos de solo lectura o recibe errores como

  • Access is denied
  • The process cannot access the file because it is being used by another process

Intente esto, os.system('rmdir /S /Q "{}"'.format(directory))

Es equivalente para rm -rf en Linux / Mac.