Menghapus folder dengan python secara rekursif


203

Saya mengalami masalah dengan menghapus direktori kosong. Ini kode saya:

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

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

Argumennya dir_to_searchadalah di mana saya melewati direktori di mana pekerjaan harus dilakukan. Direktori itu terlihat seperti ini:

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

Perhatikan bahwa semua folder di atas kosong. Ketika saya menjalankan script ini folder 20, 25sendiri akan dihapus! Tetapi folder 25dan 26tidak dihapus, meskipun mereka folder kosong.

Edit:

Pengecualian yang saya dapatkan adalah:

[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'

Di mana saya membuat kesalahan?


1
apakah Anda yakin mereka tidak memiliki file tersembunyi?
Jeff

Apakah pengecualian atau traceback dicetak? Jika demikian - akan membantu jika Anda menambahkannya ke pertanyaan
Ngure Nyaga

@ Jeff: Ya ​​saya yakin. Bahkan di mesin ubuntu saya, saya mencoba rmdir /path/to/25th/foldermenghapus seluruh direktori. Yang berarti direktori itu adalah yang kosong!
sriram

2
Kemungkinan duplikat dari Bagaimana cara menghapus / menghapus folder yang tidak kosong dengan Python? dari kedua pertanyaan DAN jawabannya
Trevor Boyd Smith

Jawaban:


392

Coba shutil.rmtree:

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

5
Apakah rmtreeseluruh direktori dihapus? Saya kira itu mirip dengan salah saturm -Rf $DIR
sriram

7
Hati-hati karena rmtree menghapus file juga. Seperti yang ditanyakan, pertanyaannya adalah bagaimana menghapus direktori KOSONG. Dokumen untuk os.walk memberikan contoh yang hampir sama persis dengan pertanyaan ini: 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

Perilaku default os.walk()adalah berjalan dari akar ke daun. Set topdown=Falsedi os.walk()berjalan dari daun ke akar.


18

Ini pathlibpenghapus tautan direktori rekursif murni saya :

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

Coba rmtree()di shutildari Python perpustakaan standar


1
Apakah rmtreeseluruh direktori dihapus? Saya kira itu mirip dengan salah saturm -Rf $DIR
sriram

2
dari docs: "Hapus seluruh pohon direktori; jalur harus mengarah ke direktori (tetapi bukan tautan simbolis ke direktori). Jika ignor_errors benar, kesalahan yang dihasilkan dari penghapusan yang gagal akan diabaikan; jika salah atau dihilangkan, kesalahan seperti itu ditangani dengan memanggil pawang yang ditentukan oleh teror atau, jika itu dihilangkan, mereka menimbulkan pengecualian. "
microo8

7

lebih baik menggunakan path absolut dan hanya mengimpor fungsi rmtree from shutil import rmtree karena ini adalah paket besar, baris di atas hanya akan mengimpor fungsi yang diperlukan.

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

1
Anda kemudian akan merujuk ini sebagai rmtree(); tidakshutil.rmtree()
Kevin Murphy

4

Hanya untuk orang berikutnya yang mencari solusi micropython, ini berfungsi murni berdasarkan os (listdir, hapus, rmdir). Itu tidak lengkap (terutama dalam penanganan kesalahan) atau mewah, namun akan berfungsi dalam sebagian besar keadaan.

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

Perintah (diberikan oleh Tomek) tidak dapat menghapus file, jika hanya dibaca . oleh karena itu, seseorang dapat menggunakan -

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
ketika mencoba kode Anda dengan folder saya sendiri yang akan dihapus, saya mendapatkan error mengatakan: NameError: name 'stat' is not defined. Bagaimana cara mendefinisikannya?
nnako

1
Modul stat mendefinisikan konstanta dan fungsi untuk menafsirkan hasil os.stat (), os.fstat () dan os.lstat (). apa yang dapat Anda coba: import os, sys from stat import *
Monir

0

Inilah solusi murni-pathlib lain , tetapi tanpa rekursi:

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

Berikut ini adalah solusi rekursif:

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

Untuk pengguna Linux, Anda cukup menjalankan perintah shell dengan cara pythonic

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

di mana rmsingkatan menghapus dan -runtuk rekursif

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.