Eliminare le cartelle in Python in modo ricorsivo


203

Sto riscontrando un problema con l'eliminazione di directory vuote. Ecco il mio codice:

for dirpath, dirnames, filenames in os.walk(dir_to_search):
    //other codes

    try:
        os.rmdir(dirpath)
    except OSError as ex:
        print(ex)

L'argomento dir_to_searchè dove sto passando la directory in cui il lavoro deve essere fatto. Quella directory è simile alla seguente:

test/20/...
test/22/...
test/25/...
test/26/...

Si noti che tutte le cartelle sopra sono vuote. Quando ho eseguito questo script le cartelle 20, 25da sola viene cancellato! Ma le cartelle 25e 26non vengono eliminate, anche se sono cartelle vuote.

Modificare:

L'eccezione che sto ottenendo sono:

[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/26'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/25'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27/tmp'

Dove sto commettendo un errore?


1
sei sicuro che non abbiano file nascosti?
Jeff,

È stata stampata un'eccezione o traceback? In tal caso, sarebbe utile se lo aggiungessi alla domanda
Ngure Nyaga,

@Jeff: Sì, ne sono sicuro. In effetti nella mia macchina Ubuntu ho provato a rmdir /path/to/25th/foldercancellare l'intera directory. Ciò significa che quella directory è vuota!
Sriram,

2
Possibile duplicato di Come rimuovo / elimino una cartella che non è vuota con Python? di entrambe le domande E le risposte
Trevor Boyd Smith,

Risposte:


392

Prova shutil.rmtree:

import shutil
shutil.rmtree('/path/to/your/dir/')

5
Ha rmtreecancellato l'intera directory? Immagino sia simile a quellorm -Rf $DIR
sriram

7
Fai attenzione perché rmtree elimina anche i file. Come è stato chiesto, la domanda era come eliminare le directory EMPTY. I documenti per os.walk forniscono un esempio che corrisponde quasi esattamente a questa domanda: import os for root, dirs, files in os.walk(top, topdown=False): for name in dirs: os.rmdir(os.path.join(root, name))
DaveSawyer


27

Il comportamento predefinito di os.walk()è camminare dalla radice alla foglia. Situato topdown=Falsea os.walk()camminare di foglia in radice.


18

Ecco il mio puro pathliblinker ricorsivo della directory:

from pathlib import Path

def rmdir(directory):
    directory = Path(directory)
    for item in directory.iterdir():
        if item.is_dir():
            rmdir(item)
        else:
            item.unlink()
    directory.rmdir()

rmdir(Path("dir/"))

12

Provate rmtree()a shutildalla libreria standard di Python


1
Ha rmtreecancellato l'intera directory? Immagino sia simile a quellorm -Rf $DIR
sriram

2
da docs: "Elimina un intero albero di directory; il percorso deve puntare a una directory (ma non un collegamento simbolico a una directory). Se ignore_errors è vero, gli errori risultanti da rimozioni non riuscite verranno ignorati; se falsi o omessi, tali errori vengono gestiti chiamando un gestore specificato da onerror o, se questo viene omesso, generano un'eccezione. "
microo8,

7

meglio usare il percorso assoluto e importare solo la funzione rmtree from shutil import rmtree poiché si tratta di un pacchetto di grandi dimensioni, la riga sopra importerà solo la funzione richiesta.

from shutil import rmtree
rmtree('directory-absolute-path')

1
Faresti quindi riferimento a questo come rmtree(); noshutil.rmtree()
Kevin Murphy,

4

Solo per il prossimo ragazzo alla ricerca di una soluzione micropython, questo funziona esclusivamente sulla base di os (listdir, remove, rmdir). Non è né completo (soprattutto nella gestione degli errori) né elaborato, tuttavia funzionerà nella maggior parte dei casi.

def deltree(target):
    print("deltree", target)
    for d in os.listdir(target):
        try:
            deltree(target + '/' + d)
        except OSError:
            os.remove(target + '/' + d)

    os.rmdir(target)

3

Il comando (dato da Tomek) non può cancellare un file, se è di sola lettura . quindi, si può usare -

import os, sys
import stat

def del_evenReadonly(action, name, exc):
    os.chmod(name, stat.S_IWRITE)
    os.remove(name)

if  os.path.exists("test/qt_env"):
    shutil.rmtree('test/qt_env',onerror=del_evenReadonly)

2
quando si cerca il codice con la mia cartella da eliminare, ottengo un errore che dice: NameError: name 'stat' is not defined. Come è stato definito?
nnako,

1
Il modulo stat definisce costanti e funzioni per l'interpretazione dei risultati di os.stat (), os.fstat () e os.lstat (). cosa puoi provare: import os, sys from stat import *
Monir

0

Ecco un'altra soluzione pure-pathlib , ma senza ricorsione:

from pathlib import Path
from typing import Union

def del_empty_dirs(base: Union[Path, str]):
    base = Path(base)
    for p in sorted(base.glob('**/*'), reverse=True):
        if p.is_dir():
            p.chmod(0o666)
            p.rmdir()
        else:
            raise RuntimeError(f'{p.parent} is not empty!')
    base.rmdir()

-1

Ecco una soluzione ricorsiva:

def clear_folder(dir):
    if os.path.exists(dir):
        for the_file in os.listdir(dir):
            file_path = os.path.join(dir, the_file)
            try:
                if os.path.isfile(file_path):
                    os.unlink(file_path)
                else:
                    clear_folder(file_path)
                    os.rmdir(file_path)
            except Exception as e:
                print(e)

-1

Per gli utenti Linux, è possibile semplicemente eseguire il comando shell in modo pitonico

import os
os.system("rm -r /home/user/folder_name")

dove rmsta per rimuovere e -rper ricorsivamente

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.