Python'daki klasörleri yinelemeli olarak silme


207

Boş dizinleri silerken sorun yaşıyorum. İşte benim kod:

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

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

Argüman dir_to_search, işin yapılması gereken dizini geçirdiğim yerdir. Bu dizin şöyle görünür:

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

Yukarıdaki tüm klasörlerin boş olduğunu unutmayın. Bu komut dosyası klasörleri çalıştırdığınızda 20, 25tek başına silinir! Ancak klasörler 25ve 26boş klasörler olsalar bile silinmez.

Düzenle:

Aldığım istisna:

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

Nerede hata yapıyorum?


1
gizli dosyaları olmadığından emin misin?
Jeff

Bir istisna veya geri izleme yazdırılıyor mu? Eğer öyleyse - bunu soruya
eklerseniz

@Jeff: Evet eminim. Aslında benim ubuntu makinemde denedim rmdir /path/to/25th/folderbütün dizini silmektir. Yani bu dizin boş bir dizin!
sriram

Yanıtlar:


396

Deneyin shutil.rmtree:

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

5
Does rmtreebütün dizin silindi? Sanırım birine benziyorrm -Rf $DIR
sriram

7
Rmtree dosyaları da sildiğinden dikkatli olun. Sorulduğu gibi, soru EMPTY dizinlerinin nasıl silineceğiydi.Oswalk için dokümanlar neredeyse bu soruya tam olarak uyan bir örnek import os for root, dirs, files in os.walk(top, topdown=False): for name in dirs: os.rmdir(os.path.join(root, name))
veriyorlar


27

Varsayılan davranışı os.walk()kökten yaprağa yürümektir. Set topdown=Falseiçinde os.walk()kök yaprak yürümek.


18

İşte benim saf pathlibözyinelemeli dizin unlinker:

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

Deneyin rmtree()in shutilPython standart kütüphaneden


1
Does rmtreebütün dizin silindi? Sanırım birine benziyorrm -Rf $DIR
sriram

2
from docs: "Tüm dizin ağacını sil; yol bir dizini işaret etmelidir (ancak bir dizine sembolik bir bağlantı olmamalıdır). ignore_errors doğruysa, başarısız kaldırma işlemlerinden kaynaklanan hatalar yok sayılır; yanlış veya atlanırsa, bu tür hatalar işlenir hata tarafından belirtilen bir işleyiciyi çağırarak veya bu belirtilmezse bir istisna oluşturur. "
microo8

7

mutlak yolu kullanmak ve sadece rmtree işlevini içe aktarmak daha iyidir, from shutil import rmtree çünkü bu büyük bir pakettir, yukarıdaki satır sadece gerekli işlevi içe aktarır .

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

1
Daha sonra buna rmtree(); değilshutil.rmtree()
Kevin Murphy

4

Sadece bir micropython çözümü arayan bir sonraki adam için, bu tamamen os (listdir, remove, rmdir) tabanlı çalışır. Ne tam (ne de özellikle hata işleme) ya da fantezi, ancak çoğu durumda işe yarayacaktır.

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

Komut (Tomek tarafından verilen) salt okunursa dosyayı silemez . bu nedenle, -

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
Silinecek kendi klasörle kodunuzu çalışırken, Şu hatayı alıyorum: NameError: name 'stat' is not defined. Nasıl tanımlandı?
nnako

1
Stat modülü os.stat (), os.fstat () ve os.lstat () sonuçlarını yorumlamak için sabitleri ve işlevleri tanımlar. deneyebileceğiniz şeyler: import os, sys stat import *
Monir

0

İşte başka bir saf-pathlib çözümü , ancak özyineleme olmadan :

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

0

Dizinleri özyinelemeli olarak kaldırmak için os.removedirs kullanabilirsiniz .

import os
os.removedirs("/home/user/folder_name")

-1

İşte özyinelemeli bir çözüm:

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

Linux kullanıcıları için, shell komutunu pitonik bir şekilde çalıştırabilirsiniz

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

nerede rmaçılımı kaldır ve -riçin yinelemeli

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.